Compare commits

..

269 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
3004 changed files with 301272 additions and 63119 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

View File

@@ -65,7 +65,7 @@ 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 detailled enough so anyone can understand digging in the code?
- [ ] 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
<!--

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',
];

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

@@ -13,7 +13,7 @@
* @link https://github.com/tecnickcom/TCPDF?tab=readme-ov-file#note TCPDF is in support only mode
*/
$sItopRootFolder = realpath(__DIR__ . "/../../../");
$sItopRootFolder = realpath(__DIR__ . "/../../../../");
$sCurrentScriptFileName = basename(__FILE__);

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

@@ -2099,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");
@@ -2273,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

@@ -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;
@@ -2323,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
@@ -2429,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()) {
@@ -2545,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);
@@ -2575,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');
@@ -3452,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);

View File

@@ -480,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'));
} );
@@ -563,8 +563,8 @@ 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;
@@ -1118,8 +1118,8 @@ JS
*/
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}";
@@ -1272,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();
@@ -1333,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'}
});

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>
@@ -271,7 +279,8 @@
</event_data>
</event>
<event id="EVENT_DB_ABOUT_TO_DELETE" _delta="define">
<description>An object is about to be deleted from the database</description>
<name>Before delete</name>
<description><![CDATA[An object is about to be deleted from the database]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
@@ -288,7 +297,8 @@
</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>
@@ -305,7 +315,9 @@
</event_data>
</event>
<event id="EVENT_ENUM_TRANSITIONS" _delta="define">
<description>Manage the allowed transitions in current object state. The only action allowed is to deny transitions with DBObject::DenyTransition()</description>
<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>
@@ -325,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>
@@ -341,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>
@@ -357,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>
@@ -374,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>
@@ -390,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>
@@ -406,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>
@@ -417,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>
@@ -426,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>
@@ -442,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>
@@ -470,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

@@ -326,6 +326,7 @@ class DataTable
$sPagesLinks = implode('', $aPagesToDisplay);
$sPagesList = '['.implode(',', array_keys($aPagesToDisplay)).']';
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
$sSelectionMode = ($iNbPages == 1) ? '' : 'positive';
$sHtml =
<<<EOF
@@ -333,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>

View File

@@ -570,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.'" },

View File

@@ -97,8 +97,8 @@ class LoginWebPage extends NiceWebPage
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');
}
/**

View File

@@ -125,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'));
@@ -138,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
@@ -269,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;
}

View File

@@ -293,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

@@ -232,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>
@@ -350,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

@@ -161,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;
@@ -368,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;
@@ -477,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;
@@ -734,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
);
}

View File

@@ -15,8 +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
@@ -73,7 +76,7 @@ class UIHTMLEditorWidget
// a) edit the file /js/ckeditor/config.js
// b) or override some of the configuration settings, using the second parameter of ckeditor()
$sJSDefineWidth = '';
$aConfig = utils::GetCkeditorPref();
$aConfig = CKEditorHelper::GetCkeditorPref();
$sWidthSpec = addslashes(trim($this->m_oAttDef->GetWidth()));
if ($sWidthSpec != '') {
/*N°6543 - the function min allow to keep text inside the column when width is defined*/
@@ -84,10 +87,20 @@ class UIHTMLEditorWidget
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

View File

@@ -99,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

@@ -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

@@ -23,7 +23,6 @@ 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 Combodo\iTop\Test\UnitTest\Application\utilsTest;
use ScssPhp\ScssPhp\Compiler;
use ScssPhp\ScssPhp\OutputStyle;
use ScssPhp\ScssPhp\ValueConverter;
@@ -2781,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

View File

@@ -33,7 +33,8 @@
"symfony/var-dumper": "~6.4.0",
"symfony/yaml": "~6.4.0",
"tecnickcom/tcpdf": "^6.6.0",
"thenetworg/oauth2-azure": "^2.0"
"thenetworg/oauth2-azure": "^2.0",
"masterminds/html5": "^2.8.0"
},
"require-dev": {
"symfony/debug-bundle": "~6.4.0",
@@ -44,9 +45,10 @@
"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": {
@@ -93,13 +95,13 @@
"require": "3.4.*"
},
"runtime": {
"dotenv_path": "symfony/.env"
"dotenv_path": "resources/symfony/.env"
}
},
"scripts": {
"post-install-cmd": ["@rmDeniedTestDir", "@tcpdfCustomFonts"],
"post-update-cmd": ["@rmDeniedTestDir", "@tcpdfCustomFonts"],
"rmDeniedTestDir": "@php .make/composer/rmDeniedTestDir.php",
"tcpdfCustomFonts": "@php .make/composer/tcpdf/tcpdfUpdateFonts.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"
}
}

69
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "f12a58e43bfb3a44aba20a73a8fd747f",
"content-hash": "c8ab1de6659dd4fa2ded6043615b86e6",
"packages": [
{
"name": "apereo/phpcas",
@@ -1018,6 +1018,73 @@
},
"time": "2023-03-17T15:20:52+00:00"
},
{
"name": "masterminds/html5",
"version": "2.9.0",
"source": {
"type": "git",
"url": "https://github.com/Masterminds/html5-php.git",
"reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
"reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
"shasum": ""
},
"require": {
"ext-dom": "*",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
}
},
"autoload": {
"psr-4": {
"Masterminds\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matt Butcher",
"email": "technosophos@gmail.com"
},
{
"name": "Matt Farina",
"email": "matt@mattfarina.com"
},
{
"name": "Asmir Mustafic",
"email": "goetas@gmail.com"
}
],
"description": "An HTML5 parser and serializer.",
"homepage": "http://masterminds.github.io/html5-php",
"keywords": [
"HTML5",
"dom",
"html",
"parser",
"querypath",
"serializer",
"xml"
],
"support": {
"issues": "https://github.com/Masterminds/html5-php/issues",
"source": "https://github.com/Masterminds/html5-php/tree/2.9.0"
},
"time": "2024-03-31T07:05:07+00:00"
},
{
"name": "nikic/php-parser",
"version": "v4.18.0",

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);
}
@@ -246,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;
}
@@ -268,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;
}
@@ -360,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

@@ -73,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
@@ -3196,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()
@@ -3293,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
}
@@ -6514,37 +6529,46 @@ class AttributeDateTime extends AttributeDBField
}
}
/**
* @inheritDoc
*
* @param int|string $proposedValue timestamp ({@see DateTime::getTimestamp()) or date as string, following the {@see GetInternalFormat} format.
*/
/**
* @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)

View File

@@ -35,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
*/
@@ -54,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()
);
}
@@ -108,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()
@@ -122,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()
);
}
@@ -172,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', '');
@@ -181,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) ||
@@ -227,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
{
@@ -413,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);
@@ -446,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);
@@ -470,7 +528,7 @@ class BulkChange
}
/**
* @param \DBObject $oTargetObj
* @param DBObject $oTargetObj
* @param array $aRowData
* @param array $aErrors
*
@@ -533,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;
@@ -602,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]);
}
}
}
@@ -680,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]);
}
}
}
@@ -788,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;
@@ -1155,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
@@ -1168,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);
@@ -1307,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)
@@ -1321,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]);
}
}
}
@@ -1446,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

@@ -549,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
*/

View File

@@ -260,7 +260,7 @@
{
$oRecipientsSearch = DBObjectSearch::FromOQL($this->Get('recipients'));
$oRecipientsSearch->AllowAllData();
$oRecipientsSet = new DBObjectSet($oRecipientsSearch);
$oRecipientsSet = new DBObjectSet($oRecipientsSearch, array(), $aContextArgs);
$bIsAsync = $this->IsAsynchronous();
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
@@ -397,6 +397,34 @@
</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">

View File

@@ -2319,16 +2319,17 @@ abstract class DBObject implements iDisplay
}
/**
* @param array $aUniquenessRuleProperties uniqueness rule properties
*
* @param string $sUniquenessRuleId uniqueness rule ID
* @return \DBSearch
* @throws \OQLException
* @throws \CoreException
*
* @internal
*
* @param string $sUniquenessRuleId uniqueness rule ID
* @param array $aUniquenessRuleProperties uniqueness rule properties
*
* @return \DBSearch
* @throws \CoreException
* @throws \OQLException
* @since 2.6.0 N°659 uniqueness constraint
* @api
* @since 2.6.0 N°659 uniqueness constraint
* @since 2.7.11 3.1.2 3.2.0 N°4314 Fix Uniqueness rules not working with Silo
*/
protected function GetSearchForUniquenessRule($sUniquenessRuleId, $aUniquenessRuleProperties)
{
@@ -4744,7 +4745,7 @@ abstract class DBObject implements iDisplay
}
}
$oDate->modify($sModifier);
$this->Set($sAttCode, $oDate->getTimestamp());
$this->Set($sAttCode, $oDate);
}
/**
@@ -5361,16 +5362,19 @@ abstract class DBObject implements iDisplay
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
*/
protected function GetReferencingObjects($bAllowAllData = false)
protected function GetReferencingObjectsForDeletion($bAllowAllData = false)
{
$aDependentObjects = array();
$aRererencingMe = MetaModel::EnumReferencingClasses(get_class($this));
foreach($aRererencingMe as $sRemoteClass => $aExtKeys)
{
/** @var \AttributeExternalKey $oExtKeyAttDef */
foreach($aExtKeys as $sExtKeyAttCode => $oExtKeyAttDef)
{
// skip if external key doesn't require the deletion cascading
if($oExtKeyAttDef->GetDeletionPropagationOption() === DEL_NONE) continue;
// skip if this external key is behind an external field
/** @var \AttributeDefinition $oExtKeyAttDef */
if (!$oExtKeyAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) continue;
$oSearch = new DBObjectSearch($sRemoteClass);
@@ -5434,13 +5438,11 @@ abstract class DBObject implements iDisplay
$this->CheckToWriteForTargetObjects(true);
$oDeletionPlan->SetDeletionIssues($this, $this->m_aDeleteIssues, $this->m_bSecurityIssue);
$aDependentObjects = $this->GetReferencingObjects(true /* allow all data */);
// Getting and setting time limit are not symmetric:
// www.php.net/manual/fr/function.set-time-limit.php#72305
$iPreviousTimeLimit = ini_get('max_execution_time');
foreach ($aDependentObjects as $aPotentialDeletes)
foreach ($this->GetReferencingObjectsForDeletion(true /* allow all data */) as $aPotentialDeletes)
{
foreach ($aPotentialDeletes as $aData)
{

View File

@@ -6,102 +6,7 @@
/** @internal Dev hack for disabling some query build optimizations (Folding/Merging) */
define('ENABLE_OPT', true);
class DBSharedSearch extends DBObjectSearch {
public function MakeSelectQuery($aOrderBy = array(), $aArgs = array(), $aAttToLoad = null, $aExtendedDataSpec = null, $iLimitCount = 0, $iLimitStart = 0, $bGetCount = false, $bBeautifulSQL = true)
{
// Check the order by specification, and prefix with the class alias
// and make sure that the ordering columns are going to be selected
//
$sClass = $this->GetClass();
$sClassAlias = $this->GetClassAlias();
$aOrderSpec = array();
foreach ($aOrderBy as $sFieldAlias => $bAscending)
{
if (!is_bool($bAscending))
{
throw new CoreException("Wrong direction in ORDER BY spec, found '$bAscending' and expecting a boolean value");
}
$iDotPos = strpos($sFieldAlias, '.');
if ($iDotPos === false)
{
$sAttClass = $sClass;
$sAttClassAlias = $sClassAlias;
$sAttCode = $sFieldAlias;
}
else
{
$sAttClassAlias = substr($sFieldAlias, 0, $iDotPos);
$sAttClass = $this->GetClassName($sAttClassAlias);
$sAttCode = substr($sFieldAlias, $iDotPos + 1);
}
if ($sAttCode != 'id')
{
MyHelpers::CheckValueInArray('field name in ORDER BY spec', $sAttCode, MetaModel::GetAttributesList($sAttClass));
$oAttDef = MetaModel::GetAttributeDef($sAttClass, $sAttCode);
foreach($oAttDef->GetOrderBySQLExpressions($sAttClassAlias) as $sSQLExpression)
{
$aOrderSpec[$sSQLExpression] = $bAscending;
}
}
else
{
$aOrderSpec['`'.$sAttClassAlias.$sAttCode.'`'] = $bAscending;
}
// Make sure that the columns used for sorting are present in the loaded columns
if (!is_null($aAttToLoad) && !isset($aAttToLoad[$sAttClassAlias][$sAttCode]))
{
$aAttToLoad[$sAttClassAlias][$sAttCode] = MetaModel::GetAttributeDef($sAttClass, $sAttCode);
}
}
/*******START difference with MakeSelectQuery **************/
$sClass = key($aAttToLoad);
$sKey = $aAttToLoad[$sClass][0];
$oObjId = new FieldExpression($sKey, $sClass);
$oSQLQuery = $this->GetSQLQuery($aOrderBy, $aArgs, [], $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, null, [$oObjId] );
/********END difference with MakeSelectQuery*************/
if ($this->m_bNoContextParameters)
{
// Only internal parameters
$aScalarArgs = $this->GetInternalParams();
}
else
{
// The complete list of arguments will include magic arguments (e.g. current_user->attcode)
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams(), $this->GetExpectedArguments());
}
try
{
$sRes = $oSQLQuery->RenderSelect($aOrderSpec, $aScalarArgs, $iLimitCount, $iLimitStart, $bGetCount, $bBeautifulSQL);
if ($sClassAlias == '_itop_')
{
IssueLog::Info('SQL Query (_itop_): '.$sRes);
}
}
catch (MissingQueryArgument $e)
{
// Add some information...
$e->addInfo('OQL', $this->ToOQL());
throw $e;
}
$this->AddQueryTraceSelect($oSQLQuery->GetSourceOQL(), $aOrderBy, $aScalarArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $sRes);
return $sRes;
}
protected function GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr = null, $aSelectExpr = null)
{
$oSQLQuery = parent::GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr, $aSelectExpr);
$oSQLQuery->SetSelect($aSelectExpr);
return $oSQLQuery;
}
}
/**
* A search over a DBObject
*
@@ -1004,15 +909,15 @@ class DBObjectSearch extends DBSearch
*/
public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
{
if (!MetaModel::IsValidKeyAttCode($this->GetClass(), $sExtKeyAttCode))
if (!MetaModel::IsValidKeyAttCode($this->GetClass(), $sExtKeyAttCode))
{
throw new CoreWarning("The attribute code '$sExtKeyAttCode' is not an external key of the class '{$this->GetClass()}'");
}
$oAttExtKey = MetaModel::GetAttributeDef($this->GetClass(), $sExtKeyAttCode);
if(!MetaModel::IsSameFamilyBranch($oFilter->GetClass(), $oAttExtKey->GetTargetClass()))
{
throw new CoreException("The specified filter (pointing to {$oFilter->GetClass()}) is not compatible with the key '{$this->GetClass()}::$sExtKeyAttCode', which is pointing to {$oAttExtKey->GetTargetClass()}");
}
throw new CoreException("The specified filter (pointing to {$oFilter->GetClass()}) is not compatible with the key '{$this->GetClass()}::$sExtKeyAttCode', which is pointing to {$oAttExtKey->GetTargetClass()}");
}
if(($iOperatorCode != TREE_OPERATOR_EQUALS) && !($oAttExtKey instanceof AttributeHierarchicalKey))
{
throw new CoreException("The specified tree operator $iOperatorCode is not applicable to the key '{$this->GetClass()}::$sExtKeyAttCode', which is not a HierarchicalKey");
@@ -1711,10 +1616,6 @@ class DBObjectSearch extends DBSearch
{
return NestedQueryExpression::FromOQLObjectQuery($oExpression->GetOQLObjectQuery());
}
elseif ($oExpression instanceof SharedQueryExpression)
{
return SharedQueryExpression::FromOQLObjectQuery($oExpression->GetOQLObjectQuery());
}
else
{
throw new CoreException('Unknown expression type', array('class'=>get_class($oExpression), 'query'=>$sQuery));

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
*/
@@ -71,12 +81,12 @@ class DesignDocument extends DOMDocument
*/
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);
return false;
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;
@@ -233,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
@@ -313,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

@@ -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

@@ -575,6 +575,12 @@ 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
@@ -1335,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;
@@ -1356,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

@@ -516,7 +516,7 @@ class ormCaseLog {
$sScript = '<script src="'.$sFileAbsUrl.'"></></script>';
$sHtml .= $sScript;
} else {
$oP->add_linked_script($sFileAbsUrl);
$oP->LinkScriptFromURI($sFileAbsUrl);
}
}
}

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

@@ -53,7 +53,7 @@ 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('allow_no_channel,force_at_least_one_channel,force_all_channels'), "sql" => "subscription_policy", "default_value" => 'allow_no_channel', "is_null_allowed" => false, "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', 'subscription_policy', 'action_list', 'complement')); // Attributes to be displayed for the complete details
@@ -185,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
@@ -385,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
}
@@ -418,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
@@ -840,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

@@ -180,17 +180,23 @@ abstract class UserRightsAddOnAPI
$sShareClass = $aShareProperties['share_class'];
$sShareAttCode = $aShareProperties['attcode'];
$oSearchShares = new DBSharedSearch($sShareClass);
$oSearchShares->AllowAllData();
$oSearchShares = new DBObjectSearch($sShareClass);
$oSearchShares->AllowAllData();
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
$oOrgField = new FieldExpression('org_id', $sShareClass);
$oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr));
$oNested = SharedQueryExpression::FromOQLObjectQuery($oSearchShares, [$sShareClass =>[$sShareAttCode]]);
$oObjId = new FieldExpression('id', $sClass);
$oFilter->MergeConditionExpression(new BinaryExpression($oObjId, 'IN', $oNested));
$aShared = array();
foreach($oSearchShares->SelectAttributeToArray($sShareAttCode) as $aRow)
{
$aShared[] = $aRow[$sShareAttCode];
}
if (count($aShared) > 0)
{
$oObjId = new FieldExpression('id', $sClass);
$oSharedIdList = ListExpression::FromScalars($aShared);
$oFilter->MergeConditionExpression(new BinaryExpression($oObjId, 'IN', $oSharedIdList));
}
}
} // if HasSharing

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

@@ -19,9 +19,19 @@ $ibo-navigation-menu--notifications--item--content--padding-x: 14px !default;
$ibo-navigation-menu--notifications--item--content--img--max-height: 100px !default;
$ibo-navigation-menu--notifications--item--content--img--padding: 5px !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--width: 10px !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--height: 10px !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-blue-500 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--width: 13px !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--height: 13px !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-red-100 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-red-500 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-orange-100 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-orange-500 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-blue-100 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-blue-500 !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-4--background-color: $ibo-navigation-menu--notifications--item--new-message-indicator--background-color !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-4--border: $ibo-navigation-menu--notifications--item--new-message-indicator--border !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--border-radius: $ibo-border-radius-full !default;
$ibo-navigation-menu--notifications--item--new-message-indicator--margin-top: $ibo-spacing-200 !default;
@@ -87,8 +97,25 @@ $ibo-popover-menu--item--no-message--image--svg--padding : 15px !default;
width: $ibo-navigation-menu--notifications--item--new-message-indicator--width;
height: $ibo-navigation-menu--notifications--item--new-message-indicator--height;
background-color: $ibo-navigation-menu--notifications--item--new-message-indicator--background-color;
border: $ibo-navigation-menu--notifications--item--new-message-indicator--border;
border-radius: $ibo-navigation-menu--notifications--item--new-message-indicator--border-radius;
margin-top: $ibo-navigation-menu--notifications--item--new-message-indicator--margin-top;
&.ibo-is-priority-1{
background-color: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color;
border: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border;
}
&.ibo-is-priority-2{
background-color: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color;
border: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border;
}
&.ibo-is-priority-3{
background-color: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color;
border: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border;
}
&.ibo-is-priority-4{
background-color: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-4--background-color;
border: $ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-4--border;
}
}
.ibo-navigation-menu--notifications-show-all-multiple ~ .ibo-popover-menu {

View File

@@ -49,10 +49,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
.ibo-input-select {
display: inline-flex;
min-width: $ibo-input-select--value--min-midth;
&:not(.ibo-input-select-autocomplete):not(.ibo-input-selectize) {
appearance: none;
}
appearance: none;
&.ibo-input-selectize {
padding-right: 0;
@@ -108,7 +105,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
outline: none !important; /* Overwrite browsers default focus outline */
}
}
&.input-active{
border: 1px solid $ibo-input--focus--border-color;
}
@@ -123,15 +120,16 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
}
.ibo-input-select-wrapper::after{
position: absolute;
z-index: 1;
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-weight: 600;
height: $ibo-input-select-wrapper--after--height;
margin-left: $ibo-input-select-wrapper--after--margin-left;
margin-top: $ibo-input-select-wrapper--after--margin-top;
padding-top: $ibo-input-select-wrapper--after--padding-top;
background-color: $ibo-input-select-wrapper--after--background-color;
color: $ibo-input-select-wrapper--after--color;
pointer-events: none;
@@ -146,6 +144,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
.ibo-input-select-wrapper--with-buttons:not(.ibo-input-select-autocomplete-wrapper)::after {
position: absolute;
z-index: 1;
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-weight: 600;
@@ -163,6 +162,7 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
}
.ibo-input-select--action-buttons{
position: absolute;
z-index: 1;
display: flex;
height: $ibo-input-select--action-button--height;
margin-top: $ibo-input-select--action-button--margin-top;

View File

@@ -8,7 +8,11 @@ $ibo-input--width: 100% !default;
$ibo-input--color: $ibo-color-grey-900 !default;
$ibo-input--background-color: $ibo-color-white-100 !default;
$ibo-input--border-color: $ibo-color-grey-500 !default;
$ibo-input--border-size: 1px !default;
$ibo-input--border-style: solid !default;
$ibo-input--border: $ibo-input--border-size $ibo-input--border-style $ibo-input--border-color !default;
$ibo-input--padding-x: 10px !default;
$ibo-input--padding-y: $ibo-spacing-0 !default;
@@ -34,13 +38,13 @@ $ibo-input--margin-x: $ibo-spacing-200 !default;
background-color: $ibo-input--background-color;
color: $ibo-input--color;
padding: $ibo-input--padding-y $ibo-input--padding-x;
border: 1px solid $ibo-input--border-color;
border: $ibo-input--border;
border-radius: $ibo-input--border-radius;
@extend %ibo-font-ral-nor-150;
&:focus{
border: 1px solid $ibo-input--focus--border-color;
border-color: $ibo-input--focus--border-color;
}
&:disabled{
background-color: $ibo-input--disabled--background-color;
@@ -54,8 +58,8 @@ textarea.ibo-input{
height:unset;
}
.ibo-input-wrapper.is-error, .ibo-input-field-wrapper.is-error {
.ibo-input, .ibo-input-vanilla, .cke, textarea {
border: 1px solid $ibo-input-wrapper--is-error--border-color;
.ibo-input, .ibo-input-vanilla, .ck-editor, textarea {
border-color: $ibo-input-wrapper--is-error--border-color;
}
.ibo-input-vanilla input{
border: 0;

View File

@@ -83,6 +83,7 @@ $ibo-object-details--header-right--padding-right--is-sticking: $ibo-spacing-300
.ibo-object-details--status + .ibo-object-details--object-class {
margin-left: 0.5rem;
display: inline-flex; /* To avoid having spaces around the class name due to the indentation */
&::before {
content: "(";

View File

@@ -21,6 +21,9 @@ $ibo-notifications--view-all--empty--svg--max-width: 30% !default;
grid-gap: $ibo-notifications--view-all--container--grid-gap;
.ibo-object-summary .ibo-panel--title{
font-size: $ibo-font-size-250;
}
.ibo-object-summary .ibo-panel--toolbar{
min-width: 102px;
}
.ibo-object-summary > .ibo-panel--body{
box-shadow: none;
@@ -53,7 +56,20 @@ $ibo-notifications--view-all--empty--svg--max-width: 30% !default;
.ibo-notifications--view-all--item--unread .ibo-panel--body::before{
background-color: $ibo-notifications--view-all--item--unread--highlight--background-color;
}
.ibo-notifications--view-all--container {
.ibo-notifications--view-all--read-action, .ibo-notifications--view-all--unread-action {
margin-left: 0 !important;
}
}
.ibo-notifications--view-all--item--read .ibo-notifications--view-all--read-action {
display: none;
}
.ibo-notifications--view-all--item--unread .ibo-notifications--view-all--unread-action {
display: none;
}
.ibo-notifications--view-all--empty {
@extend %ibo-fully-centered-content;
flex-direction: column;

View File

@@ -22,6 +22,10 @@ $ibo-vendors-ckeditor--autocomplete-item-image--border: 1px solid $ibo-color-gre
$ibo-vendors-ckeditor--autocomplete-item-title--text-color: #3A3A3A !default;
.ck-editor__editable_inline:not(.ck-comment__input *) {
min-height: 200px;
}
/* Fullscreen button (Combodo custom) */
.ibo-vendors-ckeditor--toolbar-fullscreen-button {
display: none;

View File

@@ -21,82 +21,87 @@ $ibo-vendors-selectize--item--ignore-partial--background-color: $ibo-color-grey-
$ibo-vendors-selectize--input-error--border: 1px solid $ibo-color-red-600 !default;
.selectize-dropdown-content {
max-height: unset; /* Overloaded as it will be handled by the _input-select.scss partial */
}
.selectize-input input{
color: $ibo-vendors-selectize-input--color;
.selectize-control.single .selectize-input {
box-shadow: unset;
background-color: unset;
background-image: unset;
background-repeat: unset;
}
.selectize-input,
.selectize-control.single .selectize-input.input-active {
background: unset;
cursor: text;
display: inline-flex;
}
.selectize-control.plugin-combodo_add_button{
display: flex;
.selectize-control.single .selectize-input.dropdown-active:after {
margin-top: unset;
border-width: unset;
border-color: unset;
}
.selectize-control.single .selectize-input:after {
content: unset;
}
.selectize-input::after {
content: unset;
}
.selectize-add-option {
display: inline-flex;
justify-content: center;
align-items: center;
position: absolute;
right: $ibo-vendors-selectize-control--plugin-add-button--add-option--right;
height: $ibo-vendors-selectize-control--plugin-add-button--add-option--height;
width: $ibo-vendors-selectize-control--plugin-add-button--add-option--width;
z-index: 1;
color: $ibo-vendors-selectize-control--plugin-add-button--add-option--color;
@extend %ibo-font-size-100;
.selectize-input>* {
display: inline-flex;
}
.selectize-control.single .selectize-input, .selectize-dropdown.single {
border-color: $ibo-color-grey-500;
}
.selectize-dropdown {
.selected,
.active,
.active:not(.selected){
background: #f5fafd;
color: #495c68;
}
[data-selectable],
.optgroup-header {
padding: 5px 8px;
}
.option {
opacity: 1;
}
}
// Simple options renderer
.simple-option-renderer--container {
display: flex;
align-items: center;
}
.simple-option-renderer--container--icon {
width: 25px;
text-align: center;
}
.simple-option-renderer--container--label {
margin-left: 3px;
flex-grow: 1;
}
.selectize-input{
.attribute-set-item{
>* {
// Bulk modification: add / remove / partial items states
.selectize-input {
.attribute-set-item {
> * {
display: inline;
}
&.item-add::before,&.item-remove::before{
&.item-add::before,&.item-remove::before {
@extend %fa-solid-base;
margin-right: $ibo-vendors-selectize--item--icon--margin-right;
}
&.item-add{
&.item-add {
background-color: $ibo-vendors-selectize--item--add--background-color !important;
&::before{
&::before {
color: $ibo-vendors-selectize--item--add--icon--color;
content: '\f067';
}
}
&.item-remove{
&.item-remove {
background-color: $ibo-vendors-selectize--item--remove--background-color !important;
&::before{
&::before {
color: $ibo-vendors-selectize--item--remove--icon--color;
content: '\f1f8';
}
}
&.item-ignore-partial{
&.item-ignore-partial {
background-color: $ibo-vendors-selectize--item--ignore-partial--background-color !important;
}
}
&.selectize-input-error{
&.selectize-input-error {
border: $ibo-vendors-selectize--input-error--border;
}
}
}

4
css/c3.min.css vendored
View File

@@ -1 +1,5 @@
/*
* @deprecated 3.2.0 N°5621 Moved to NPM
*/
.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000}

View File

@@ -3,18 +3,32 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
/* These rules should be the same as those in css/backoffice/vendors/ckeditor.css */
body{
margin: 5px 10px;
.ibo-mention-item{
line-height: 1.6rem;
}
.cke_editable{
line-height: 1.4;
[data-role="object-mention"]{
color: #0782C1;
}
figure{
border: solid 1px #ccc;
border-radius: 2px;
}
p{
margin-top: 0.25em;
margin-bottom: 0.25em;
[data-role="object-mention"]:hover{
color: #2b6bb0;
}
.ck.ck-editor.cke-maximized{
position: fixed;
left: 0px;
top:0px;
right: 0px;
bottom: 0px;
z-index: 999;
display: flex;
flex-direction: column;
}
.ck.ck-editor.cke-maximized .ck.ck-editor__main{
flex-grow: 1;
}
.ck.ck-editor.cke-maximized .ck-editor__editable_inline:not(.ck-comment__input *){
height: 100%;
}

View File

@@ -16,11 +16,11 @@
/* Shortened version style */
.ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
.ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
.ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }

View File

@@ -1,3 +1,7 @@
/**
* @deprecated 3.2.0 N°5621 Moved to NPM
*/
/*!
* jQuery contextMenu - Plugin for simple contextMenu handling
*

View File

@@ -1,3 +1,7 @@
/*
* @deprecated 3.2.0 N°5621 Moved to NPM
*/
/* Magnific Popup CSS */
.mfp-bg {
top: 0;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -58,6 +58,9 @@ $progress-bar-error-bg-color: #F56565 !default;
.center {
text-align: center;
}
.hidden {
display: none;
}
/* Animations */
@keyframes progress_bar_color_ongoing {

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<branding>
<themes>
<theme id="fullmoon-high-contrast" _delta="define">
<variables>
</variables>
<imports>
<import id="fullmoon-high-contrast-scss-variables" xsi:type="variables">combodo-backoffice-fullmoon-high-contrast-theme/scss/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="fullmoon">../css/backoffice/main.scss</stylesheet>
<stylesheet id="high-contrast-stylesheet">combodo-backoffice-fullmoon-high-contrast-theme/scss/stylesheet.scss</stylesheet>
</stylesheets>
<precompiled_stylesheet>combodo-backoffice-fullmoon-high-contrast-theme/precompiled-themes/main.css</precompiled_stylesheet>
</theme>
</themes>
</branding>
</itop_design>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Localized data
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
* 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/>
*/
Dict::Add('EN US', 'English', 'English', array(
'theme:fullmoon-high-contrast' => 'Fullmoon (High contrast)',
));

View File

@@ -0,0 +1,25 @@
<?php
/**
* Localized data
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
* 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/>
*/
Dict::Add('FR FR', 'French', 'Français', array(
'theme:fullmoon-high-contrast' => 'Fullmoon (Contraste élevé)',
));

View File

@@ -0,0 +1,51 @@
<?php
//
// iTop module definition file
//
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'combodo-backoffice-fullmoon-high-contrast-theme/3.2.0',
array(
// Identification
//
'label' => 'Backoffice: Fullmoon with high contrast accessibility theme',
'category' => 'business',
// Setup
//
'dependencies' => array(
),
'mandatory' => true,
'visible' => false,
// Components
//
'datamodel' => array(
),
'webservice' => array(
),
'data.struct' => array(
// add your 'structure' definition XML files here,
),
'data.sample' => array(
// add your sample data XML files here,
),
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(
// Module specific settings go here, if any
),
)
);
?>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,145 @@
$ibo-high-contrast--thin-border: solid 1px $ibo-color-grey-900 !default;
$ibo-high-contrast--medium-border: solid 2px $ibo-color-grey-900 !default;
$ibo-alert--icon--font-size: 3rem !default;
$ibo-alert--icon--top: calc(50% - #{$ibo-alert--icon--font-size} / 2) !default;
$ibo-alert--icon--left: $ibo-spacing-500 !default;
$ibo-alert--icon--opacity: 0.8 !default;
$ibo-alert--icons: (
'success': '\f00c',
'information': '\f129',
'warning': '\f12a',
'danger': '\f071',
'failure': '\f071',
'error': '\f071',
) !default;
$ibo-toast--icon--font-size: 2rem !default;
$ibo-toast--icon--top: calc(50% - #{$ibo-toast--icon--font-size} / 2) !default;
$ibo-toast--icon--left: $ibo-spacing-400 !default;
@each $sName, $sIcon in $ibo-alert--icons {
%ibo-alert-#{$sName}, .ibo-alert.ibo-is-#{$sName} {
&::after {
content: $sIcon;
@extend %fa-solid-base;
position: absolute;
top: $ibo-alert--icon--top;
left: $ibo-alert--icon--left;
opacity: $ibo-alert--icon--opacity;
font-size: $ibo-alert--icon--font-size;
width: $ibo-alert--icon--font-size;
text-align: center;
}
.ibo-alert--body, .ibo-alert--title {
padding-left: calc(#{$ibo-alert--icon--left} + #{$ibo-alert--icon--font-size});
}
}
.ibo-toast.ibo-is-#{$sName} {
&::after{
font-size: $ibo-toast--icon--font-size !important;
top: $ibo-toast--icon--top !important;
left: $ibo-toast--icon--left !important;
width: $ibo-toast--icon--font-size !important;
}
padding-left: calc(#{$ibo-toast--padding-left} / 2 + #{$ibo-toast--icon--left} + #{$ibo-toast--icon--font-size});
}
}
.ibo-navigation-menu--notifications--item--new-message-indicator{
border: none !important;
background-color: transparent !important;
&.ibo-is-priority-1::before{
content: "\f12a \f12a \f12a";
@extend %fa-solid-base;
color: $ibo-color-danger-900;
}
&.ibo-is-priority-2::before{
content: "\f12a \f12a";
@extend %fa-solid-base;
color: $ibo-color-warning-900;
}
&.ibo-is-priority-3::before{
content: "\f12a";
@extend %fa-solid-base;
color: $ibo-color-success-900;
}
&.ibo-is-priority-4::before{
content: "\f129";
@extend %fa-solid-base;
color: $ibo-color-information-900;
}
}
.ibo-navigation-menu--menu-nodes ul li > a:hover, .ibo-navigation-menu--menu-node-counter{
border: $ibo-high-contrast--thin-border;
}
.ibo-top-bar{
box-shadow: none;
border-bottom: $ibo-high-contrast--medium-border;
}
.ibo-breadcrumbs--item-icon > span, .ibo-breadcrumbs--item-icon > img{
opacity: 1 !important;
}
.ibo-tab-container--tabs-list{
border-bottom: $ibo-high-contrast--thin-border;
}
.ibo-tab-container--extra-tabs-list{
border: $ibo-high-contrast--thin-border;
}
.ibo-datatable tbody > tr {
border-bottom: $ibo-high-contrast--thin-border;
}
.ibo-activity-panel--tab-toolbar{
border-bottom: $ibo-high-contrast--thin-border;
border-top: $ibo-high-contrast--thin-border;
}
.ibo-activity-entry--main-information{
border: $ibo-high-contrast--thin-border;
}
.ibo-activity-entry--medallion.ibo-has-image{
box-shadow: none;
border: $ibo-high-contrast--thin-border;
}
.ibo-activity-panel--tab-toggler.ibo-is-active .ibo-activity-panel--tab-title{
border-left: $ibo-high-contrast--thin-border;
border-right: $ibo-high-contrast--thin-border;
font-weight: 800;
}
.ibo-button{
border: $ibo-high-contrast--thin-border;
}
@each $sColor, $aColorValues in $ibo-alert-colors {
$highlight-color: nth($aColorValues, 2);
%ibo-alert-#{$sColor}, .ibo-alert.ibo-is-#{$sColor} {
border: 1px solid $highlight-color;
}
}
.ibo-pill{
border: 1px solid var(--ibo-main-color--900);
}
@each $sType, $aColors in $ibo-pill-states-colors {
.ibo-pill.ibo-is-#{$sType} {
border: 1px solid map-get($aColors, 'secondary-color');
}
}
.ibo-quick-create, .ibo-global-search{
border-left: $ibo-high-contrast--thin-border;
border-right: $ibo-high-contrast--thin-border;
}
.ibo-popover-menu{
border: $ibo-high-contrast--thin-border;
}
.ibo-popover-menu--item:not(:last-child){
border-bottom: $ibo-high-contrast--thin-border;
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<branding>
<themes>
<theme id="fullmoon-protanopia-deuteranopia" _delta="define">
<variables>
</variables>
<imports>
<import id="fullmoon-prota-deutera-scss-variables" xsi:type="variables">combodo-backoffice-fullmoon-protanopia-deuteranopia-theme/scss/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="fullmoon">../css/backoffice/main.scss</stylesheet>
<stylesheet id="stylesheet">combodo-backoffice-fullmoon-protanopia-deuteranopia-theme/scss/stylesheet.scss</stylesheet>
</stylesheets>
<precompiled_stylesheet>combodo-backoffice-fullmoon-protanopia-deuteranopia-theme/precompiled-themes/main.css</precompiled_stylesheet>
</theme>
</themes>
</branding>
</itop_design>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Localized data
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
* 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/>
*/
Dict::Add('EN US', 'English', 'English', array(
'theme:fullmoon-protanopia-deuteranopia' => 'Fullmoon (Protanopia & Deuteranopia)'
));

View File

@@ -0,0 +1,25 @@
<?php
/**
* Localized data
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
* 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/>
*/
Dict::Add('FR FR', 'French', 'Français', array(
'theme:fullmoon-protanopia-deuteranopia' => 'Fullmoon (Protanopie et Deuteranopie)'
));

View File

@@ -0,0 +1,51 @@
<?php
//
// iTop module definition file
//
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'combodo-backoffice-fullmoon-protanopia-deuteranopia-theme/3.2.0',
array(
// Identification
//
'label' => 'Backoffice: Fullmoon with protonopia & deuteranopia accessibility theme',
'category' => 'business',
// Setup
//
'dependencies' => array(
),
'mandatory' => true,
'visible' => false,
// Components
//
'datamodel' => array(
),
'webservice' => array(
),
'data.struct' => array(
// add your 'structure' definition XML files here,
),
'data.sample' => array(
// add your sample data XML files here,
),
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(
// Module specific settings go here, if any
),
)
);
?>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,114 @@
$ibo-color-primary-100: $ibo-color-blue-100;
$ibo-color-primary-200: $ibo-color-blue-200;
$ibo-color-primary-300: $ibo-color-blue-300;
$ibo-color-primary-400: $ibo-color-blue-400;
$ibo-color-primary-500: $ibo-color-blue-500;
$ibo-color-primary-600: $ibo-color-blue-600;
$ibo-color-primary-700: $ibo-color-blue-700;
$ibo-color-primary-800: $ibo-color-blue-800;
$ibo-color-primary-900: $ibo-color-blue-900;
$ibo-color-primary-950: $ibo-color-blue-950;
$ibo-color-danger-100: $ibo-color-orange-100;
$ibo-color-danger-200: $ibo-color-orange-200;
$ibo-color-danger-300: $ibo-color-orange-300;
$ibo-color-danger-400: $ibo-color-orange-400;
$ibo-color-danger-500: $ibo-color-orange-500;
$ibo-color-danger-600: $ibo-color-orange-600;
$ibo-color-danger-700: $ibo-color-orange-700;
$ibo-color-danger-800: $ibo-color-orange-800;
$ibo-color-danger-900: $ibo-color-orange-900;
$ibo-color-danger-950: $ibo-color-orange-950;
$ibo-color-yellow-100: #fefce8;
$ibo-color-yellow-200: #fef9c3;
$ibo-color-yellow-300: #fef08a;
$ibo-color-yellow-400: #fde047;
$ibo-color-yellow-500: #facc15;
$ibo-color-yellow-600: #eab308;
$ibo-color-yellow-700: #ca8a04;
$ibo-color-yellow-800: #a16207;
$ibo-color-yellow-900: #854d0e;
$ibo-color-yellow-950: #713f12;
$ibo-color-warning-100: $ibo-color-yellow-100;
$ibo-color-warning-200: $ibo-color-yellow-200;
$ibo-color-warning-300: $ibo-color-yellow-300;
$ibo-color-warning-400: $ibo-color-yellow-400;
$ibo-color-warning-500: $ibo-color-yellow-500;
$ibo-color-warning-600: $ibo-color-yellow-600;
$ibo-color-warning-700: $ibo-color-yellow-700;
$ibo-color-warning-800: $ibo-color-yellow-800;
$ibo-color-warning-900: $ibo-color-yellow-900;
$ibo-color-warning-950: $ibo-color-yellow-950;
$ibo-color-success-100: $ibo-color-blue-100;
$ibo-color-success-200: $ibo-color-blue-200;
$ibo-color-success-300: $ibo-color-blue-300;
$ibo-color-success-400: $ibo-color-blue-400;
$ibo-color-success-500: $ibo-color-blue-500;
$ibo-color-success-600: $ibo-color-blue-600;
$ibo-color-success-700: $ibo-color-blue-700;
$ibo-color-success-800: $ibo-color-blue-800;
$ibo-color-success-900: $ibo-color-blue-900;
$ibo-color-success-950: $ibo-color-blue-950;
$ibo-color-information-100: #f1f5f9;
$ibo-color-information-200: #e2e8f0;
$ibo-color-information-300: #cbd5e1;
$ibo-color-information-400: #94a3b8;
$ibo-color-information-500: #64748b;
$ibo-color-information-600: #475569;
$ibo-color-information-700: #334155;
$ibo-color-information-800: #1e293b;
$ibo-color-information-900: #0f172a;
$ibo-color-information-950: #020617;
$ibo-lifecycle-new-state-primary-color: $ibo-color-information-600;
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-information-600;
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-yellow-700;
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-success-state-primary-color: $ibo-color-blue-700;
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-failure-state-primary-color: $ibo-color-orange-800;
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-information-200;
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-information-700;
$ibo-lifecycle-active-state-primary-color: $ibo-color-blue-700;
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-yellow-700;
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100;
$ibo-caselog-highlight-color-1: $ibo-color-blue-700;
$ibo-caselog-highlight-color-2: $ibo-color-yellow-700;
$ibo-caselog-highlight-color-3: $ibo-color-information-600;
$ibo-caselog-highlight-color-4: $ibo-color-yellow-500;
$ibo-caselog-highlight-color-5: $ibo-color-blue-500;
$ibo-caselog-highlight-color-6: $ibo-color-yellow-300;
$ibo-caselog-highlight-color-7: $ibo-color-blue-300;
$ibo-input-wrapper--is-error--border-color: $ibo-color-warning-700;
$ibo-field-validation: $ibo-color-warning-800;
$ibo-navigation-menu--visual-hint--background-color: $ibo-color-blue-400;
$ibo-wizard-container--background-color: $ibo-color-information-200;
$ibo-wizard-container--border-color: $ibo-color-information-600;
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-danger-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-danger-500;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-warning-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-warning-500;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-success-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-success-500;
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-blue-600;

View File

@@ -0,0 +1,73 @@
$ibo-alert--icon--font-size: 3rem !default;
$ibo-alert--icon--top: calc(50% - #{$ibo-alert--icon--font-size} / 2) !default;
$ibo-alert--icon--left: $ibo-spacing-500 !default;
$ibo-alert--icon--opacity: 0.3 !default;
$ibo-alert--icons: (
'success': '\f00c',
'information': '\f129',
'warning': '\f12a',
'danger': '\f071',
'failure': '\f071',
'error': '\f071',
) !default;
$ibo-toast--icon--font-size: 2rem !default;
$ibo-toast--icon--top: calc(50% - #{$ibo-toast--icon--font-size} / 2) !default;
$ibo-toast--icon--left: $ibo-spacing-400 !default;
@each $sName, $sIcon in $ibo-alert--icons {
%ibo-alert-#{$sName}, .ibo-alert.ibo-is-#{$sName} {
&::after {
content: $sIcon;
@extend %fa-solid-base;
position: absolute;
top: $ibo-alert--icon--top;
left: $ibo-alert--icon--left;
opacity: $ibo-alert--icon--opacity;
font-size: $ibo-alert--icon--font-size;
width: $ibo-alert--icon--font-size;
text-align: center;
}
.ibo-alert--body, .ibo-alert--title {
padding-left: calc(#{$ibo-alert--icon--left} + #{$ibo-alert--icon--font-size});
}
}
.ibo-toast.ibo-is-#{$sName} {
&::after{
font-size: $ibo-toast--icon--font-size !important;
top: $ibo-toast--icon--top !important;
left: $ibo-toast--icon--left !important;
width: $ibo-toast--icon--font-size !important;
}
padding-left: calc(#{$ibo-toast--padding-left} / 2 + #{$ibo-toast--icon--left} + #{$ibo-toast--icon--font-size});
}
}
.ibo-navigation-menu--notifications--item--new-message-indicator{
border: none !important;
background-color: transparent !important;
&.ibo-is-priority-1::before{
content: "\f12a \f12a \f12a";
@extend %fa-solid-base;
color: $ibo-color-danger-700;
}
&.ibo-is-priority-2::before{
content: "\f12a \f12a";
@extend %fa-solid-base;
color: $ibo-color-warning-700;
}
&.ibo-is-priority-3::before{
content: "\f12a";
@extend %fa-solid-base;
color: $ibo-color-success-700;
}
&.ibo-is-priority-4::before{
content: "\f129";
@extend %fa-solid-base;
color: $ibo-color-information-700;
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<branding>
<themes>
<theme id="fullmoon-tritanopia" _delta="define">
<variables>
</variables>
<imports>
<import id="fullmoon-trita-scss-variables" xsi:type="variables">combodo-backoffice-fullmoon-tritanopia-theme/scss/scss-variables.scss</import>
</imports>
<stylesheets>
<stylesheet id="fullmoon">../css/backoffice/main.scss</stylesheet>
<stylesheet id="stylesheet">combodo-backoffice-fullmoon-tritanopia-theme/scss/stylesheet.scss</stylesheet>
</stylesheets>
<precompiled_stylesheet>combodo-backoffice-fullmoon-tritanopia-theme/precompiled-themes/main.css</precompiled_stylesheet>
</theme>
</themes>
</branding>
</itop_design>

View File

@@ -0,0 +1,26 @@
<?php
/**
* Localized data
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
* 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/>
*/
Dict::Add('EN US', 'English', 'English', array(
'theme:fullmoon-tritanopia' => 'Fullmoon (Tritanopia)',
));

View File

@@ -0,0 +1,25 @@
<?php
/**
* Localized data
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
* 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/>
*/
Dict::Add('FR FR', 'French', 'Français', array(
'theme:fullmoon-tritanopia' => 'Fullmoon (Tritanopie)',
));

View File

@@ -0,0 +1,51 @@
<?php
//
// iTop module definition file
//
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'combodo-backoffice-fullmoon-tritanopia-theme/3.2.0',
array(
// Identification
//
'label' => 'Backoffice: Fullmoon with tritanopia accessibility theme',
'category' => 'business',
// Setup
//
'dependencies' => array(
),
'mandatory' => true,
'visible' => false,
// Components
//
'datamodel' => array(
),
'webservice' => array(
),
'data.struct' => array(
// add your 'structure' definition XML files here,
),
'data.sample' => array(
// add your sample data XML files here,
),
// Documentation
//
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
'doc.more_information' => '', // hyperlink to more information, if any
// Default settings
//
'settings' => array(
// Module specific settings go here, if any
),
)
);
?>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,78 @@
$ibo-color-yellow-100: #fefce8;
$ibo-color-yellow-200: #fef9c3;
$ibo-color-yellow-300: #fef08a;
$ibo-color-yellow-400: #fde047;
$ibo-color-yellow-500: #facc15;
$ibo-color-yellow-600: #eab308;
$ibo-color-yellow-700: #ca8a04;
$ibo-color-yellow-800: #a16207;
$ibo-color-yellow-900: #854d0e;
$ibo-color-yellow-950: #713f12;
$ibo-color-success-100: $ibo-color-blue-100;
$ibo-color-success-200: $ibo-color-blue-200;
$ibo-color-success-300: $ibo-color-blue-300;
$ibo-color-success-400: $ibo-color-blue-400;
$ibo-color-success-500: $ibo-color-blue-500;
$ibo-color-success-600: $ibo-color-blue-600;
$ibo-color-success-700: $ibo-color-blue-700;
$ibo-color-success-800: $ibo-color-blue-800;
$ibo-color-success-900: $ibo-color-blue-900;
$ibo-color-success-950: $ibo-color-blue-950;
$ibo-color-information-100: #f1f5f9;
$ibo-color-information-200: #e2e8f0;
$ibo-color-information-300: #cbd5e1;
$ibo-color-information-400: #94a3b8;
$ibo-color-information-500: #64748b;
$ibo-color-information-600: #475569;
$ibo-color-information-700: #334155;
$ibo-color-information-800: #1e293b;
$ibo-color-information-900: #0f172a;
$ibo-color-information-950: #020617;
$ibo-lifecycle-new-state-primary-color: $ibo-color-information-600;
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-information-600;
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-red-200;
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-red-800;
$ibo-lifecycle-success-state-primary-color: $ibo-color-blue-700;
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-failure-state-primary-color: $ibo-color-red-800;
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-information-200;
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-information-700;
$ibo-lifecycle-active-state-primary-color: $ibo-color-blue-700;
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100;
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-red-700;
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100;
$ibo-caselog-highlight-color-1: $ibo-color-blue-700;
$ibo-caselog-highlight-color-2: $ibo-color-red-700;
$ibo-caselog-highlight-color-3: $ibo-color-information-600;
$ibo-caselog-highlight-color-4: $ibo-color-red-500;
$ibo-caselog-highlight-color-5: $ibo-color-blue-500;
$ibo-caselog-highlight-color-6: $ibo-color-red-300;
$ibo-caselog-highlight-color-7: $ibo-color-blue-300;
$ibo-input-wrapper--is-error--border-color: $ibo-color-pink-700;
$ibo-field-validation: $ibo-color-pink-800;
$ibo-navigation-menu--visual-hint--background-color: $ibo-color-pink-600;
$ibo-wizard-container--background-color: $ibo-color-information-200;
$ibo-wizard-container--border-color: $ibo-color-information-600;
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-pink-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-pink-600;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-warning-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-warning-400;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-success-100;
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-success-500;
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-pink-500;

View File

@@ -0,0 +1,73 @@
$ibo-alert--icon--font-size: 3rem !default;
$ibo-alert--icon--top: calc(50% - #{$ibo-alert--icon--font-size} / 2) !default;
$ibo-alert--icon--left: $ibo-spacing-500 !default;
$ibo-alert--icon--opacity: 0.3 !default;
$ibo-alert--icons: (
'success': '\f00c',
'information': '\f129',
'warning': '\f12a',
'danger': '\f071',
'failure': '\f071',
'error': '\f071',
) !default;
$ibo-toast--icon--font-size: 2rem !default;
$ibo-toast--icon--top: calc(50% - #{$ibo-toast--icon--font-size} / 2) !default;
$ibo-toast--icon--left: $ibo-spacing-400 !default;
@each $sName, $sIcon in $ibo-alert--icons {
%ibo-alert-#{$sName}, .ibo-alert.ibo-is-#{$sName} {
&::after {
content: $sIcon;
@extend %fa-solid-base;
position: absolute;
top: $ibo-alert--icon--top;
left: $ibo-alert--icon--left;
opacity: $ibo-alert--icon--opacity;
font-size: $ibo-alert--icon--font-size;
width: $ibo-alert--icon--font-size;
text-align: center;
}
.ibo-alert--body, .ibo-alert--title {
padding-left: calc(#{$ibo-alert--icon--left} + #{$ibo-alert--icon--font-size});
}
}
.ibo-toast.ibo-is-#{$sName} {
&::after{
font-size: $ibo-toast--icon--font-size !important;
top: $ibo-toast--icon--top !important;
left: $ibo-toast--icon--left !important;
width: $ibo-toast--icon--font-size !important;
}
padding-left: calc(#{$ibo-toast--padding-left} / 2 + #{$ibo-toast--icon--left} + #{$ibo-toast--icon--font-size});
}
}
.ibo-navigation-menu--notifications--item--new-message-indicator{
border: none !important;
background-color: transparent !important;
&.ibo-is-priority-1::before{
content: "\f12a \f12a \f12a";
@extend %fa-solid-base;
color: $ibo-color-danger-700;
}
&.ibo-is-priority-2::before{
content: "\f12a \f12a";
@extend %fa-solid-base;
color: $ibo-color-warning-700;
}
&.ibo-is-priority-3::before{
content: "\f12a";
@extend %fa-solid-base;
color: $ibo-color-success-700;
}
&.ibo-is-priority-4::before{
content: "\f129";
@extend %fa-solid-base;
color: $ibo-color-information-700;
}
}

View File

@@ -23,6 +23,9 @@
<module>itop-hub-connector</module>
<module>itop-oauth-client</module>
<module>combodo-backoffice-darkmoon-theme</module>
<module>combodo-backoffice-fullmoon-high-contrast-theme</module>
<module>combodo-backoffice-fullmoon-protanopia-deuteranopia-theme</module>
<module>combodo-backoffice-fullmoon-tritanopia-theme</module>
<module>itop-themes-compat</module>
</modules>
<mandatory>true</mandatory>

View File

@@ -115,7 +115,7 @@
$this->SetIfNull('user_id', $iUserId);
// Get Contact from user
$oUser = MetaModel::GetObject('User', $iUserId);
$oUser = MetaModel::GetObject('User', $iUserId, true, true);
$this->SetIfNull('contact_id', $oUser->Get('contactid'));
}
return parent::DBInsertNoReload();
@@ -266,7 +266,8 @@
</classes>
<events>
<event id="EVENT_ADD_ATTACHMENT_TO_OBJECT" _delta="define">
<description>An attachment has been added to an object</description>
<name>Attachment added</name>
<description><![CDATA[An attachment has been added to an object]]></description>
<replaces>Attachment::AfterUpdate</replaces>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
@@ -287,7 +288,8 @@
</event_data>
</event>
<event id="EVENT_REMOVE_ATTACHMENT_FROM_OBJECT" _delta="define">
<description>An attachment has been removed from an object</description>
<name>Attachment removed</name>
<description><![CDATA[An attachment has been removed from an object]]></description>
<replaces>Attachment::AfterUpdate</replaces>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>

View File

@@ -267,6 +267,23 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
}
}
/**
*
* @see ObjectFormManager::FinalizeAttachments() for the portal version
*
* @param $oObject
* @param $oChange
*
* @return void
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \DeleteException
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
protected static function UpdateAttachments($oObject, $oChange = null)
{
self::$m_bIsModified = false;

View File

@@ -185,6 +185,7 @@ abstract class AbstractAttachmentsRenderer
{
$sClass = $this->sObjClass;
$sId = $this->iObjKey;
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
$iMaxUploadInBytes = AttachmentPlugIn::GetMaxUploadSize();
$sMaxUploadLabel = AttachmentPlugIn::GetMaxUpload();
$sFileTooBigLabel = Dict::Format('Attachments:Error:FileTooLarge', $sMaxUploadLabel);
@@ -195,15 +196,15 @@ abstract class AbstractAttachmentsRenderer
$oAddButton = FileSelectUIBlockFactory::MakeStandard('file', 'file');
$oAddButton->SetShowFilename(false);
$this->oPage->AddUiBlock($oAddButton);
$this->oPage->add('<span style="display:none;" id="attachment_loading"><img src="../images/indicator.gif"></span> '.$sMaxUploadLabel);
$this->oPage->add('<span style="display:none;" id="attachment_loading"><img src="' . $sAppRootUrl . 'images/indicator.gif"></span> ' . $sMaxUploadLabel);
$this->oPage->add('</div>');
$this->oPage->add('<div class="ibo-attachment--upload-file--drop-zone-hint ibo-svg-illustration--container">');
$this->oPage->add(file_get_contents(APPROOT.'images/illustrations/undraw_upload.svg'));
$this->oPage->add(Dict::S('UI:Attachments:DropYourFileHint').'</div>');
$this->oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
$this->oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.fileupload.js');
$this->oPage->LinkScriptFromAppRoot('node_modules/blueimp-file-upload/js/jquery.iframe-transport.js');
$this->oPage->LinkScriptFromAppRoot('node_modules/blueimp-file-upload/js/jquery.fileupload.js');
$this->oPage->add_ready_script(
<<<JS
@@ -275,7 +276,7 @@ abstract class AbstractAttachmentsRenderer
e.stopPropagation();
})
$(document).bind('dragover', function (e) {
$(document).on('dragover', function (e) {
var bFiles = false;
if (e.dataTransfer && e.dataTransfer.types)
{
@@ -316,7 +317,7 @@ abstract class AbstractAttachmentsRenderer
window.dropZoneCnt++;
});
$(document).bind('dragend dragleave drop', function(event){
$(document).on('dragend dragleave drop', function(event){
window.dropZoneCnt--;
if(window.dropZone && window.dropZoneCnt === 0){
window.dropZone.removeClass('ibo-drag-in');
@@ -333,16 +334,16 @@ abstract class AbstractAttachmentsRenderer
$(this).addClass('image-in-use').find('img').wrap('<div class="image-in-use-wrapper" style="position:relative;display:inline-block;"></div>');
}
});
$('.htmlEditor').each(function() {
var oEditor = $(this).ckeditorGet();
var sHtml = oEditor.getData();
var jElement = $('<div/>').html(sHtml).contents();
jElement.find('img').each(function() {
var sSrc = $(this).attr('src');
$('.attachment a[href="'+sSrc+'"]').parent().addClass('image-in-use').find('img').wrap('<div class="image-in-use-wrapper" style="position:relative;display:inline-block;"></div>');
});
});
$('.image-in-use-wrapper').append('<div style="position:absolute;top:0;left:0;"><img src="../images/transp-lock.png"></div>');
// $('.htmlEditor').each(function() {
// var oEditor = $(this).ckeditorGet();
// var sHtml = oEditor.getData();
// var jElement = $('<div/>').html(sHtml).contents();
// jElement.find('img').each(function() {
// var sSrc = $(this).attr('src');
// $('.attachment a[href="'+sSrc+'"]').parent().addClass('image-in-use').find('img').wrap('<div class="image-in-use-wrapper" style="position:relative;display:inline-block;"></div>');
// });
// });
$('.image-in-use-wrapper').append('<div style="position:absolute;top:0;left:0;"><img src="' + GetAbsoluteUrlModulesRoot() + 'images/transp-lock.png"></div>');
}, 200 );
JS
);

View File

@@ -993,34 +993,6 @@
}
]]></code>
</method>
<method id="SetClosureDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>StimulusUserAction</type>
<code><![CDATA[ public function SetClosureDate($sStimulusCode)
{
$this->Set('close_date', time());
return true;
}]]></code>
</method>
<method id="ResetRejectReason">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function ResetRejectReason($sStimulusCode)
{
$this->Set('reason', '');
return true;
}]]></code>
</method>
<method id="OnInsert">
<static>false</static>
<access>protected</access>

View File

@@ -535,48 +535,6 @@
}
]]></code>
</method>
<method id="SetApprovalDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function SetApprovalDate($sStimulusCode)
{
$this->Set('approval_date', time());
return true;
}]]></code>
</method>
<method id="ResetRejectReason">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function ResetRejectReason($sStimulusCode)
{
$this->Set('reject_reason', '');
return true;
}]]></code>
</method>
<method id="SetClosureDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function SetClosureDate($sStimulusCode)
{
$this->Set('close_date', time());
return true;
}]]></code>
</method>
<method id="OnInsert">
<static>false</static>
<access>protected</access>

View File

@@ -80,7 +80,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkContactToFunctionalCI' => 'Lien Contact / CI Fonctionel',
'Class:lnkContactToFunctionalCI' => 'Lien Contact / CI Fonctionnel',
'Class:lnkContactToFunctionalCI+' => '',
'Class:lnkContactToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_id' => 'CI',
@@ -98,7 +98,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:FunctionalCI' => 'CI fonctionnel',
'Class:FunctionalCI' => 'CI Fonctionnel',
'Class:FunctionalCI+' => '',
'Class:FunctionalCI/Attribute:name' => 'Nom',
'Class:FunctionalCI/Attribute:name+' => '',
@@ -1214,7 +1214,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkFunctionalCIToOSPatch' => 'Lien CI Fonctionel / Patch OS',
'Class:lnkFunctionalCIToOSPatch' => 'Lien CI Fonctionnel / Patch OS',
'Class:lnkFunctionalCIToOSPatch+' => '',
'Class:lnkFunctionalCIToOSPatch/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_id' => 'Patch OS',
@@ -1449,7 +1449,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkApplicationSolutionToFunctionalCI' => 'Lien Solution Applicative / CI Fonctionel',
'Class:lnkApplicationSolutionToFunctionalCI' => 'Lien Solution Applicative / CI Fonctionnel',
'Class:lnkApplicationSolutionToFunctionalCI+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_id' => 'Solution applicative',
@@ -1559,7 +1559,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkDocumentToFunctionalCI' => 'Lien Document / CI Fonctionel',
'Class:lnkDocumentToFunctionalCI' => 'Lien Document / CI Fonctionnel',
'Class:lnkDocumentToFunctionalCI+' => '',
'Class:lnkDocumentToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_id' => 'CI',

View File

@@ -109,10 +109,11 @@ ApplicationMenu::CheckMenuIdEnabled('ConfigEditor');
$oP = new iTopWebPage(Dict::S('config-edit-title'));
$oP->set_base(utils::GetAbsoluteUrlAppRoot().'pages/');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'/js/ace/ace.js');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'/js/ace/mode-php.js');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'/js/ace/theme-eclipse.js');
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot().'/js/ace/ext-searchbox.js');
$sAceDir = 'node_modules/ace-builds/src-min/';
$oP->LinkScriptFromAppRoot($sAceDir.'ace.js');
$oP->LinkScriptFromAppRoot($sAceDir.'mode-php.js');
$oP->LinkScriptFromAppRoot($sAceDir.'theme-eclipse.js');
$oP->LinkScriptFromAppRoot($sAceDir.'ext-searchbox.js');
try {
$sOperation = utils::ReadParam('operation', '');

View File

@@ -45,6 +45,7 @@ class UpdateController extends Controller
$aParams['sFileUploadMaxSize'] = utils::BytesToFriendlyFormat($aParams['iFileUploadMaxSize']);
$aParams['sPostMaxSize'] = ini_get('post_max_size');
$aParams['sUploadMaxSize'] = ini_get('upload_max_filesize');
$aParams['bDontUpgradeIfIntegrityFailed'] = !utils::IsDevelopmentEnvironment();
$oFilter = DBObjectSearch::FromOQL('SELECT ModuleInstallation WHERE parent_id=0 AND name!="datamodel"');
$oSet = new DBObjectSet($oFilter, ['installed' => false]); // Most recent first
$aParams['oSet'] = $oSet;
@@ -129,7 +130,6 @@ class UpdateController extends Controller
$sTransactionId = utils::GetNewTransactionId();
$aParams['sTransactionId'] = $sTransactionId;
$this->AddSaas('css/backoffice/main.scss');
$this->m_sOperation = 'ConfirmUpdate';
$this->DisplaySetupPage($aParams);
}
@@ -158,7 +158,6 @@ class UpdateController extends Controller
'sAjaxURL' => utils::GetAbsoluteUrlAppRoot().'/pages/UI.php',
];
$this->AddLinkedScript(utils::GetAbsoluteUrlAppRoot().'setup/jquery.progression.js');
$this->AddSaas('css/backoffice/main.scss');
$this->AddSaas('env-'.utils::GetCurrentEnvironment().'/itop-core-update/css/itop-core-update.scss');
$this->m_sOperation = 'UpdateCoreFiles';
$this->DisplaySetupPage($aParams);

View File

@@ -28,10 +28,17 @@ $.ajax({
$("#file-container").removeClass("ibo-is-hidden");
$("#check-in-progress").addClass("ibo-is-hidden");
} else {
$("#check-update").prop("disabled", true);
$("#file").prop("disabled", true);
$('#form-update-outer').slideUp(600);
oRequirements.addClass("ibo-is-failure");
{% if bDontUpgradeIfIntegrityFailed %}
$("#check-update").prop("disabled", true);
$("#file").prop("disabled", true);
$('#form-update-outer').slideUp(600);
{% else %}
$("#check-update").prop("disabled", false);
$("#file").prop("disabled", false);
$("#file-container").removeClass("ibo-is-hidden");
$("#check-in-progress").addClass("ibo-is-hidden");
{% endif %}
}
}
});
@@ -55,7 +62,7 @@ var oGetDBDiskSpace = $.ajax({
method: "POST",
url: "{{ sAjaxURL|raw }}",
data: {
route: "core_update_ajax.get_d_b_disk_space",
route: "core_update_ajax.get_db_disk_space",
maintenance: true
},
dataType: "json",

View File

@@ -17,7 +17,7 @@ class HubConnectorPage extends NiceWebPage
$sModuleImagesDir = utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/images';
$sUserPrefs = appUserPreferences::GetAsJSON();
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
$this->LinkScriptFromAppRoot('js/utils.js');
$this->add_script(<<<JS
var oUserPreferences = $sUserPrefs;
JS

View File

@@ -57,7 +57,7 @@ function DisplayStatus(WebPage $oPage)
function DoLanding(WebPage $oPage)
{
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/css/hub.css');
$oPage->LinkStylesheetFromModule('itop-hub-connector/css/hub.css');
$oPage->add('<table class="module-selection-banner"><tr>');
$sBannerUrl = utils::GetAbsoluteUrlModulesRoot().'/itop-hub-connector/images/landing-extension.png';
$oPage->add('<td><img style="max-height:72px; margin-right: 10px;" src="'.$sBannerUrl.'"/><td>');
@@ -138,7 +138,7 @@ function DoInstall(WebPage $oPage)
$sUID = hash('sha256', rand());
file_put_contents(APPROOT.'data/hub/compile_authent', $sUID);
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/css/hub.css');
$oPage->LinkStylesheetFromModule('itop-hub-connector/css/hub.css');
$oPage->add('<table class="module-selection-banner"><tr>');
$sBannerUrl = utils::GetAbsoluteUrlModulesRoot().'/itop-hub-connector/images/landing-extension.png';
$oPage->add('<td><img style="max-height:72px; margin-right: 10px;" src="'.$sBannerUrl.'"/><td>');
@@ -214,7 +214,7 @@ function DoInstall(WebPage $oPage)
$oPage->add('</div>'); // module-selection-body
$oPage->add_linked_stylesheet('../css/font-awesome/css/all.min.css');
$oPage->LinkStylesheetFromAppRoot('css/font-awesome/css/all.min.css');
$oPage->add('<div id="hub_installation_widget"></div>');
@@ -263,8 +263,8 @@ try {
}
$oPage = new SetupPage(''); // Title will be set later, depending on $sOperation
$oPage->add_linked_script(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/js/hub.js');
$oPage->add_linked_stylesheet('../css/font-combodo/font-combodo.css');
$oPage->LinkScriptFromModule('itop-hub-connector/js/hub.js');
$oPage->LinkStylesheetFromAppRoot('css/font-combodo/font-combodo.css');
$oPage->add_style(<<<CSS
div.choice { margin: 0.5em;}

View File

@@ -305,9 +305,9 @@ try {
$sCloseUrl = utils::GetAbsoluteUrlModulesRoot().'/itop-hub-connector/images/black-close.svg';
$oPage = new HubConnectorPage(Dict::S('iTopHub:Connect'));
$oPage->add_linked_script(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/js/hub.js');
$oPage->add_linked_stylesheet('../css/font-combodo/font-combodo.css');
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/css/hub.css');
$oPage->LinkScriptFromModule('itop-hub-connector/js/hub.js');
$oPage->LinkStylesheetFromAppRoot('css/font-combodo/font-combodo.css');
$oPage->LinkStylesheetFromModule('itop-hub-connector/css/hub.css');
$aDataToPost = MakeDataToPost($sTargetRoute);

View File

@@ -1083,64 +1083,6 @@
}
]]></code>
</method>
<method id="SetAssignedDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function SetAssignedDate($sStimulusCode)
{
$this->Set('assignment_date', time());
return true;
}]]></code>
</method>
<method id="SetLastPendingDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function SetLastPendingDate($sStimulusCode)
{
$this->Set('last_pending_date', time());
return true;
}]]></code>
</method>
<method id="SetResolveDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() and SetElapsedTime() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function SetResolveDate($sStimulusCode)
{
$this->Set('resolution_date', time());
$iTimeSpent = time() - AttributeDateTime::GetAsUnixSeconds($this->Get('start_date'));
$this->Set('time_spent', $iTimeSpent);
return true;
}]]></code>
</method>
<method id="SetClosureDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
* @return void
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function SetClosureDate($sStimulusCode)
{
$this->Set('close_date', time());
return true;
}]]></code>
</method>
<method id="DoCheckToWrite">
<static>false</static>
<access>public</access>
@@ -1238,67 +1180,6 @@
}
}]]></code>
</method>
<method id="resolveChilds">
<comment><![CDATA[/**
* To be deprecated: use ResolveChildTickets() instead
*/]]></comment>
<static>false</static>
<access>public</access>
<type>LifecycleAction</type>
<code><![CDATA[ public function resolveChilds($sStimulusCode)
{
if (MetaModel::IsValidClass('UserRequest'))
{
$sOQL = "SELECT UserRequest WHERE parent_incident_id=:ticket";
$oChildRequestSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL),
array(),
array(
'ticket' => $this->GetKey(),
)
);
//automatically resolve child requests
while($oRequest = $oChildRequestSet->Fetch())
{
if ( $oRequest->Get('status') != 'resolved')
{
$oRequest->set('servicesubcategory_id',$this->Get('servicesubcategory_id'));
$oRequest->set('service_id',$this->Get('service_id'));
$oRequest->set('team_id',$this->Get('team_id'));
$oRequest->set('agent_id',$this->Get('agent_id'));
$oRequest->set('resolution_code',$this->Get('resolution_code'));
$oRequest->set('solution','Automatically resolved by incident:[[Incident:'.$this->Get('ref').']]');
$oRequest->ApplyStimulus('ev_autoresolve');
$oRequest->DBUpdate();
}
}
}
//automatically resolve child incidents
$sOQL = "SELECT Incident WHERE parent_incident_id=:ticket";
$oChildIncidentSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL),
array(),
array(
'ticket' => $this->GetKey(),
)
);
while($oIncident = $oChildIncidentSet->Fetch())
{
if ( $oIncident->Get('status') != 'resolved')
{
$oIncident->set('servicesubcategory_id',$this->Get('servicesubcategory_id'));
$oIncident->set('service_id',$this->Get('service_id'));
$oIncident->set('team_id',$this->Get('team_id'));
$oIncident->set('agent_id',$this->Get('agent_id'));
$oIncident->set('resolution_code',$this->Get('resolution_code'));
$oIncident->set('solution','Automatically resolved by incident:[[Incident:'.$this->Get('ref').']]');
$oIncident->ApplyStimulus('ev_autoresolve');
$oIncident->DBUpdate();
}
}
return true;
}]]></code>
</method>
<method id="ResolveChildTickets">
<comment><![CDATA[/**
* Cascade the resolution to child User Request and Incidents

View File

@@ -2,7 +2,8 @@
<itop_design version="3.2">
<events>
<event id="EVENT_DISPLAY_OBJECT_DETAILS" _delta="define">
<description>An object details is about to be displayed to a user</description>
<name>Portal object displayed</name>
<description><![CDATA[An object details is about to be displayed to a user on a portal]]></description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>

View File

@@ -29,6 +29,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use UserRights;
use utils;
/**
* Class UserProvider
@@ -44,6 +45,8 @@ class UserProvider
private $sPortalId;
/** @var \User $oUser */
private $oUser;
/** @var bool $bUserCanLogOff Whether the current user can log off or not */
private $bUserCanLogOff;
/** @var array $aAllowedPortals */
private $aAllowedPortals;
@@ -89,6 +92,9 @@ class UserProvider
throw new Exception('Could not load connected user.');
}
// User allowed to log off or not
$this->bUserCanLogOff = utils::CanLogOff();
// Allowed portals
$aAllowedPortals = UserRights::GetAllowedPortals();
@@ -119,6 +125,15 @@ class UserProvider
return $this->oUser;
}
/**
* @return bool {@see static::$bUserCanLogOff}
* @since 3.1.2 3.2.0
*/
public function getCurrentUserCanLogOff(): bool
{
return $this->bUserCanLogOff;
}
/**
* Get allowed portals.
*

View File

@@ -1463,6 +1463,8 @@ class ObjectFormManager extends FormManager
// Remove attachments that are no longer attached to the current object
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentsIds))
{
$aData = ['attachment' => $oAttachment];
$this->oObject->FireEvent(EVENT_REMOVE_ATTACHMENT_FROM_OBJECT, $aData);
$oAttachment->DBDelete();
$aActions[] = self::GetAttachmentActionChangeOp($oAttachment, false);
}
@@ -1487,6 +1489,8 @@ class ObjectFormManager extends FormManager
$oAttachment->Set('temp_id', '');
$oAttachment->DBUpdate();
$aActions[] = self::GetAttachmentActionChangeOp($oAttachment, true);
$aData = ['attachment' => $oAttachment];
$this->oObject->FireEvent(EVENT_ADD_ATTACHMENT_TO_OBJECT, $aData);
}
}

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