Compare commits

..

541 Commits

Author SHA1 Message Date
XavierGR
1c2f923811 Fix missing dot 2025-04-18 11:17:54 +02:00
XavierGR
24b2852830 Log warning when integer is set to invalid value 2025-04-18 11:16:52 +02:00
XavierGR
5ba44a03ea Add computed tag for attribute computation from OQL Expression 2025-04-18 08:04:38 +02:00
Stephen Abello
96382377ee N°8274 - Polishing new look portal (#707)
* Remove precompiled CSS files

* Fix mosaic design, polish mosaic and treeview hover colors

* Fix modal close button not being visible, clean modal code

* Fix mandatory and tooltip indicator on fields

* Fix treeview filter data display

* N°8274 - Improve profile brick display

* N°8274 - Use ipb alert instead of bootstrap alerts

* N°8274 - Make sure dropdown items use all available space

* N°8274 - Remove class name from the object brick title and add it to a separate title complement

* N°8274 - Polishing new look portal
- La police des informations dans l'annonce est trop petite (Quitte a agrandir le bloc information pour ne pas perdre de ligne d'affichage)

* N°8274 - Add visual indicator to selected tab

* N°8274 - Set the icon url to home page if it's not customized

* N°8274 - Polishing new look portal
- fix manage bricks pills click event

* N°8274 - Make panel title and tab text bigger

* N°8274 - Make datatables more similar to backoffice

* Add precompiled stylesheets

---------

Co-authored-by: Benjamin <benjamin.dalsass@combodo.com>
2025-03-31 15:41:55 +02:00
Stephen Abello
84708fb327 Merge branch 'support/3.2' into develop 2025-03-26 09:31:38 +01:00
Stephen Abello
bf8269fee1 N°8293 - Make multiple modal in portal correctly stack the backdrops 2025-03-26 09:26:04 +01:00
Romain Quetiez
02adca0a1f 🎨 N°8231 Code format and comments 2025-03-25 11:48:23 +01:00
jf-cbd
90370fce3b Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/composer.json
2025-03-24 11:45:49 +01:00
jf-cbd
c99995563e Merge remote-tracking branch 'origin/support/3.2.1' into support/3.2
# Conflicts:
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_static.php
2025-03-24 11:31:25 +01:00
jf-cbd
7af1cdebfa Workaround for N°4459 doesn't work on 3.2 2025-03-24 11:21:41 +01:00
jf-cbd
a9fb5cd182 N°7870 - Tests: access the symfony service container to instantiate services 2025-03-24 11:02:34 +01:00
jf-cbd
9010504902 Fix tests 2025-03-24 10:53:18 +01:00
jf-cbd
2625b1ab54 Update tests for 3.1 2025-03-24 10:52:47 +01:00
Molkobain
b967338c48 🐛 N°8278 - Avoid autoloaders class name conflict by ensuring all existing have a unique name (#704)
* 🐛 Avoid autoloaders class name conflict by ensuring all existing have a unique name

* 🐛 Redump itop-attachments autoloaders for correct suffix
2025-03-24 10:15:09 +01:00
jf-cbd
10fbea5f4d Fix merge conflict 2025-03-24 10:09:33 +01:00
jf-cbd
e49b8fc480 Merge remote-tracking branch 'origin/support/2.7' into support/3.2.1
# Conflicts:
#	core/restservices.class.inc.php
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_static.php
2025-03-24 10:07:36 +01:00
jf-cbd
4a415fdb59 N°8215 - When PHP warning are enabled, Global Request doesn't work 2025-03-21 14:44:18 +01:00
jf-cbd
5232694c04 N°8281 - Unable to click search button in multiple request template 2025-03-21 11:20:37 +01:00
Eric Espie
2a87d0aa15 N°8242 - When editing a dashboard the parameters do not refresh as expected 2025-03-18 17:40:10 +01:00
Anne-Cath
a103c458cb N°8272 - Portal : Unable to save a date in French format - rollback removed code for N°7145 2025-03-18 16:58:50 +01:00
jf-cbd
fe913524fd Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-13 16:04:19 +01:00
Tommaso Rossi
9a895a7fbd 🐛 N°8115 - Unattended Install: unable to connect to MySQL with TLS (#694)
🐛 Support TLS connections to MySQL in unattended-install process
2025-03-13 15:59:04 +01:00
jf-cbd
9f2375999a Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectTest.php
2025-03-13 15:57:15 +01:00
jf-cbd
f5011bb200 N°8260 - Change format of REST logs when they are close to the SQL field size limit 2025-03-13 15:39:00 +01:00
jf-cbd
29c75f626b N°8259 - Problem with GetMaxSize on AttributeText 2025-03-13 15:29:00 +01:00
jf-cbd
4b86639d71 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-12 11:55:15 +01:00
jf-cbd
0562563cbb Dump autoloader 2025-03-12 11:51:59 +01:00
jf-cbd
40068bd913 Merge remote-tracking branch 'origin/support/2.7' into support/3.2
# Conflicts:
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_static.php
2025-03-12 11:47:33 +01:00
jf-cbd
874a5fd2ce Dump autoloader 2025-03-12 11:36:06 +01:00
Stephen Abello
911a204f37 N°4685 - Fix padding in browse brick's treeview toolbar 2025-03-07 10:39:42 +01:00
jf-cbd
69f9a0b369 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-06 16:25:43 +01:00
jf-cbd
1ec139782e Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-03-06 16:24:40 +01:00
jf-cbd
056dce4d78 Merge remote-tracking branch 'origin/support/2.7' into support/3.1
# Conflicts:
#	webservices/rest.php
2025-03-06 16:12:15 +01:00
jf-cbd
063bb9680e N°8231 - Better variable fallback 2025-03-06 16:09:51 +01:00
jf-cbd
25e8ec38d6 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-06 15:31:19 +01:00
jf-cbd
9b1395db03 Workaround for N°4459 doesn't work on 3.2 2025-03-06 15:23:38 +01:00
jf-cbd
8fd9eb6a84 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-03-06 14:58:24 +01:00
jf-cbd
1142bf327c Fix tests 2025-03-06 14:54:18 +01:00
jf-cbd
278496eaf6 Update tests for 3.1 2025-03-06 14:40:39 +01:00
jf-cbd
77ba0b398f Fix merge conflict 2025-03-06 12:11:20 +01:00
jf-cbd
04ca7bf603 Merge remote-tracking branch 'origin/support/2.7' into support/3.1
# Conflicts:
#	core/restservices.class.inc.php
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
#	tests/php-unit-tests/unitary-tests/core/Delta/delta_test_sanitize_output.xml
#	tests/php-unit-tests/unitary-tests/core/RestServicesSanitizeOutputTest.php
#	tests/php-unit-tests/unitary-tests/core/RestServicesTest.php
#	webservices/rest.php
2025-03-06 12:10:00 +01:00
jf-cbd
8f8ac46f55 N°8215 - When PHP warning are enabled, Global Request doesn't work 2025-03-06 11:59:08 +01:00
denis.flaven@combodo.com
07b904ee1b N°8231 - making rest api logs more readable 2025-03-06 11:59:08 +01:00
Stephen Abello
1574993a28 N°4685 - Update precompiled stylesheets 2025-03-06 10:35:51 +01:00
Stephen Abello
43120bfb60 N°4685 - Make user card display nicer when user's name is short 2025-03-06 10:31:11 +01:00
Stephen Abello
9c1a1d08a1 N°4685 - Fix navigation menu hover having the same color as regular background 2025-03-06 10:30:53 +01:00
Stephen Abello
f095f93326 N°4684 - Align portal default theme with backoffice one (#702)
* Prepare SCSS files and move nav menu / main wrapper from Bootstrap positioning

* Small work on navigation menu

* Split bootstrap theme file into multiple files inside themes/

* Fix unit test missing css/ import path

* Better display for usercard

* Upload precompiled portal stylesheets to fix unit test based on portal.css

* Polish menu

* Stylize home tiles

* Stylize home tiles and layout pages

* Stylize home tiles and layout pages

* Stylize home tiles and layout pages

* Stylize home tiles and layout pages

* Define default font in a more elegant way

* Small implementation for open/close navigation_menu

* Fix navigation menu dropdown menu not working

* Fix menu colors

* Set  <html> lang attribute

* Add accessibility attributes to menu toggler

* Fix bricks / page title dot spacing

* new look adaptation

* Fix padding in manage brick

* Fix menu entries font size and color

* Change manage export color

* Fix icon size in tiles

* Add style to manage brick panels

* Redesign browse brick mosaic view

* Fix variable name collision

* - Set templates cache in dev mode to 1s
- Implements components classes JS
- Move navigations layouts outside the global layout
- Update tiles

* Fix tile description font size

* Redesign browse brick tree mode

* Tweak navigation menu css

* - use custom elements for js components
- adjust layouts

* Modify forms/modals

* Modify method name following code review

* Add a dropdown element to replace bootstrap one

* improvement to dropdown

* datatable prevent column sort icon to wrap

* update composer json file.
Without classmap-authoritative flag, classmap are not generated
There is no test folder

* remove colored circle in manage brick tile titles

* remove white span between title and title additional part in brick layout

* convert navigation menu js to custom element

* navigation menu (WIP)

* Improvement to dropdown

* Fix some caselog classes

* Improvement to dropdown

* Improvement to dropdown

* navigation menu (WIP)

* portal ui version  2025

* datatable sort icon issue on link sets

* portal ui settings

* Fix dropdown for browse brick

* add portal scss colors

* add alerts scss=

* Buttons improvement

* Correction list table action issue

* responsive adjustments

* restore ben-j erased stephen

* ipb-button integration

* remove table header bottom border

* remove brick page ipb-page--main-header duplicate

* Adjust button styel

* Fix browse brick buttons

* Correctly overload approot and fix scsss imports

* Fix treeview expand buttons, fix mosaic first display glitch and add animation to each mosaic tile drawn

* Fix treeview toolbar

* remove wrap from ipb-button-groups

* Fix hover and clickable space in mosaics

* Clean dropdown css

* Fix dropdown menu content for a better display

* Align pagination buttons with theme buttons

* Align pagination buttons with theme buttons

* Fix drowdown

* Add precompiled stylesheets for merge to main branch

---------

Co-authored-by: Benjamin Dalsass <95754414+bdalsass@users.noreply.github.com>
2025-03-05 14:31:00 +01:00
Eric Espie
c9c3b6c108 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-05 11:15:54 +01:00
Eric Espie
5aee7f4722 N°8242 - When editing a dashboard the parameters do not refresh as expected 2025-03-05 11:02:19 +01:00
Eric Espie
292701b71c N°8242 - When editing a dashboard the parameters do not refresh as expected 2025-03-04 16:51:58 +01:00
jf-cbd
5caddf81b8 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-03 17:08:14 +01:00
jf-cbd
533b57ab99 Merge branch 'support/3.1' into support/3.2 2025-03-03 17:07:24 +01:00
jf-cbd
be8d348b25 N°8231 - Update tests 2025-03-03 16:49:27 +01:00
jf-cbd
6c7a98fe3d Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2025-03-03 16:38:32 +01:00
denis.flaven@combodo.com
ec2203229b N°8231 - making rest api log more readable 2025-03-03 16:23:25 +01:00
jf-cbd
73fe07a745 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-03-03 14:38:35 +01:00
jf-cbd
2f699d355a Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-03-03 14:37:57 +01:00
jf-cbd
da4457f5b4 Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2025-03-03 14:36:50 +01:00
denis.flaven@combodo.com
97848cea4f N°8231 - making rest api log more readable 2025-03-03 11:38:52 +01:00
jf-cbd
1760727879 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-02-25 11:40:02 +01:00
jf-cbd
2ccd883c9a 👥 Update contributor list 2025-02-25 11:38:54 +01:00
jf-cbd
eabd68ff77 👥 Update contributor list 2025-02-25 11:38:14 +01:00
jf-cbd
d982652228 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-02-25 09:22:04 +01:00
jf-cbd
2b493787b1 Update itop-version-history.md with 2.7.12, 3.1.3 and 3.2.1 2025-02-25 09:19:47 +01:00
Timothee
1d26cac8e3 Fix translations 2025-02-21 18:23:31 +01:00
Timothee
cc47d27fd8 Merge branch 'support/3.2' into develop
# Conflicts:
#	datamodels/2.x/itop-attachments/dictionaries/cs.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/da.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/de.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/es_cr.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/fr.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/hu.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/it.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/ja.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/nl.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/pl.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/pt_br.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/ru.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/sk.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/tr.dict.itop-attachments.php
#	datamodels/2.x/itop-attachments/dictionaries/zh_cn.dict.itop-attachments.php
#	datamodels/2.x/itop-config-mgmt/dictionaries/it.dict.itop-config-mgmt.php
#	datamodels/2.x/itop-config/dictionaries/it.dict.itop-config.php
#	datamodels/2.x/itop-incident-mgmt-itil/dictionaries/it.dict.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/dictionaries/it.dict.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-portal/dictionaries/it.dict.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/dictionaries/it.dict.itop-problem-mgmt.php
#	datamodels/2.x/itop-request-mgmt-itil/dictionaries/it.dict.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/dictionaries/it.dict.itop-request-mgmt.php
#	dictionaries/cs.dictionary.itop.core.php
#	dictionaries/da.dictionary.itop.core.php
#	dictionaries/de.dictionary.itop.core.php
#	dictionaries/es_cr.dictionary.itop.core.php
#	dictionaries/fr.dictionary.itop.core.php
#	dictionaries/fr.dictionary.itop.ui.php
#	dictionaries/hu.dictionary.itop.core.php
#	dictionaries/it.dictionary.itop.core.php
#	dictionaries/it.dictionary.itop.ui.php
#	dictionaries/ja.dictionary.itop.core.php
#	dictionaries/nl.dictionary.itop.core.php
#	dictionaries/pl.dictionary.itop.core.php
#	dictionaries/pt_br.dictionary.itop.core.php
#	dictionaries/ru.dictionary.itop.core.php
#	dictionaries/sk.dictionary.itop.core.php
#	dictionaries/tr.dictionary.itop.core.php
#	dictionaries/ui/components/quick-create/cs.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/da.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/de.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/es_cr.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/fr.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/hu.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/it.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/ja.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/nl.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/pl.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/pt_br.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/ru.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/sk.dictionary.itop.quick-create.php
#	dictionaries/ui/components/quick-create/tr.dictionary.itop.quick-create.php
2025-02-21 17:58:13 +01:00
jf-cbd
d74c850621 N°7870 - Tests: access the symfony service container to instantiate services 2025-02-21 15:28:38 +01:00
jf-cbd
4e575e17a3 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-02-21 13:23:57 +01:00
jf-cbd
94d6eca0c1 N°8215 - When PHP warning are enabled, Global Request doesn't work 2025-02-21 13:20:27 +01:00
jf-cbd
355da8ec0a Merge remote-tracking branch 'origin/support/2.7' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
2025-02-21 13:18:19 +01:00
jf-cbd
5f006c45db N°8215 - When PHP warning are enabled, Global Request doesn't work 2025-02-21 13:16:07 +01:00
jf-cbd
1e5334ab2b Update comment on logout.html.twig 2025-02-11 09:43:33 +01:00
Anne-Cath
05419f3d7f N°7216 import improves error handling missing or null data - fix test 2025-02-07 22:59:59 +01:00
Eric Espie
a9bc4973b4 N°8139 - Fix ApplyStimulus during post update 2025-02-07 17:24:43 +01:00
Timothee
e93d909a38 🌐 Dictionaries update 2025-02-07 15:36:58 +01:00
jf-cbd
534b087a2c N°8163 - Increase page redirection timeout on logout 2025-02-07 14:36:01 +01:00
Eric Espie
14346e0895 N°8139 - Avoid double writing in lifecycle action 2025-02-07 11:10:14 +01:00
Eric Espie
6985e366c2 N°8139 - Avoid double writing in lifecycle action 2025-02-07 10:58:13 +01:00
denis.flaven@combodo.com
e85ec6bb47 Merge branch 'support/3.2' into develop 2025-02-07 10:36:32 +01:00
denis.flaven@combodo.com
cf57549370 Merge branch 'support/3.1' into support/3.2 2025-02-07 10:29:24 +01:00
denis.flaven@combodo.com
46aaeb4301 Merge branch 'support/2.7' into support/3.1 2025-02-07 10:24:18 +01:00
Eric Espie
7ddc593869 🔊 enhance crud logs 2025-02-07 10:14:39 +01:00
denis.flaven@combodo.com
affed69999 Version number bump. 2025-02-07 10:09:48 +01:00
Anne-Cath
533fe0ae01 N°7216 import improves error handling missing or null data - case if an ext key use more than 1 field for reconciliation add test 2025-02-06 17:43:18 +01:00
Anne-Cath
efd117eac7 N°7216 import improves error handling missing or null data - case if an ext key use more than 1 field for reconciliation 2025-02-06 17:28:47 +01:00
jf-cbd
01a17b5f9b Merge branch 'support/3.2' into develop 2025-02-06 17:13:58 +01:00
jf-cbd
695f357054 N°8170 - Issue with Ckeditor and precanned reply
N°8152 - CKEditor : Style and list button are the same
2025-02-06 17:11:53 +01:00
Eric Espie
0088580798 Better specific delta detection for tests 2025-02-05 17:40:57 +01:00
Ben
92d49c6c47 Adding new modules 2025-02-04 11:56:57 +01:00
Ben
f6298370a7 Adding new modules 2025-02-04 11:56:32 +01:00
jf-cbd
623d2823ff Fix merge conflict 2025-02-04 11:29:19 +01:00
jf-cbd
5d5849b724 Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php
2025-02-04 10:52:18 +01:00
jf-cbd
bd6ccc55f8 N°8150 - Better picture checking 2025-02-04 10:49:54 +01:00
XGUI
3a497524dc N°8129 - Fix unexpected identifier self 2025-02-04 10:48:28 +01:00
XGUI
902e2259a9 N°8129 - Remove duplicated test method 2025-02-04 10:33:35 +01:00
XGUI
b87fb65ac4 Merge branch 'support/3.2' into develop
# Conflicts:
#	core/attributedef.class.inc.php
#	datamodels/2.x/version.xml
#	tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
#	tests/php-unit-tests/unitary-tests/core/AttributeDefinitionTest.php
2025-02-04 10:14:41 +01:00
denis.flaven@combodo.com
4c1da328ce Merge support/3.1 into support/3.2 2025-01-31 17:20:33 +01:00
denis.flaven@combodo.com
64a216e0f6 Merge branch 'support/2.7' into support/3.1 2025-01-31 17:13:09 +01:00
denis.flaven@combodo.com
d5754fc568 N°8135 - Bump datamodel version. 2025-01-31 17:04:56 +01:00
Tommaso Rossi
ab929571c7 🐛 N°8115 - Unattended Install: unable to connect to MySQL with TLS (#694)
🐛 Support TLS connections to MySQL in unattended-install process
2025-01-31 14:45:52 +01:00
Anne-Catherine
8e0e01ad40 N°7216 import improves error handling missing or null data (#612)
Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
2025-01-30 16:14:14 +01:00
Anne-Catherine
8a604c643e N°7371 - Remembers the choice done in the popup that appears when saving public and private logs at the same time (#636) 2025-01-30 15:55:34 +01:00
XGUI
5851b2e1ff N°8129 - Fix missing namespace backslash 2025-01-30 15:06:00 +01:00
XGUI
803ebfbe33 N°8129 - Dont crash if date/time default value has a bad format 2025-01-30 14:14:31 +01:00
odain
d12c8a183c N°8143 - Setup page in error in support.combodo.com 2025-01-30 11:16:07 +01:00
Anne-Cath
7bbd4b4726 N°8144 - Issue using Organization filtering box 2025-01-30 10:10:36 +01:00
odain
c8754725b0 N°8143 - Setup page in error in support.combodo.com 2025-01-29 16:42:43 +01:00
XGUI
f1594ad974 Merge remote-tracking branch 'origin/develop' into develop 2025-01-29 15:58:06 +01:00
XGUI
805e208e32 Merge branch 'issue/8129-dont_crash_if_datetime_default_value_has_bad_format' into develop 2025-01-29 15:56:50 +01:00
XGUI
9e3f99a150 N°8129 - Dont crash if date/time default value has a bad format 2025-01-29 15:55:20 +01:00
XGUI
e9d21bca39 N°8129 Handle badly formatted default date (e.g. "27/01/2025") 2025-01-29 15:35:26 +01:00
XGUI
807283505d N°8129 - Dont crash if date/time default value has a bad format 2025-01-29 11:08:21 +01:00
Eric Espie
71244e5c15 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-29 09:37:10 +01:00
Eric Espie
a3c911e93e N°8139 - Avoid double writing in lifecycle action 2025-01-29 09:32:21 +01:00
Eric Espie
72e0750c1b Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-28 11:13:05 +01:00
Eric Espie
38e0fb27f1 N°8131 - Issue on DBlinkchange event when object is deleted 2025-01-28 11:12:11 +01:00
Eric Espie
4b4197d910 N°8131 - Issue on DBlinkchange event when object is deleted 2025-01-28 11:09:31 +01:00
jf-cbd
ac8004561b Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-28 10:53:15 +01:00
jf-cbd
c5189b7d33 N°8134 - Fix import after merge 2025-01-28 10:52:29 +01:00
jf-cbd
b0288bc08e Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php
2025-01-28 10:44:35 +01:00
Eric Espie
52097f5e12 N°8131 - Issue on DBlinkchange event when object is deleted 2025-01-28 10:33:11 +01:00
jf-cbd
ccb1ca9d79 Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2025-01-28 10:32:18 +01:00
jf-cbd
44290db312 N°8134 - Portal user profile is broken, regression from 7776 2025-01-28 10:23:44 +01:00
Eric Espie
65e49e2139 N°8139 - Avoid double writing in lifecycle action 2025-01-27 17:34:46 +01:00
Eric Espie
b1bf89807d Add CRUD logs 2025-01-27 15:06:11 +01:00
Eric Espie
766d3b51ad Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-24 14:36:14 +01:00
Eric Espie
39c59f46fd Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-01-24 14:35:48 +01:00
Eric Espie
025af923ea N°8131 - Issue on DBlinkchange event when object is delete 2025-01-24 14:23:50 +01:00
Eric Espie
3215bffbcb Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-24 12:07:13 +01:00
Eric Espie
c2aecad9d2 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-01-24 12:06:49 +01:00
v-dumas
986e900a99 N°7145 - Inline & Attachment add default expire for MailToTicket 2025-01-24 12:03:16 +01:00
Eric Espie
858b12abaa N°8131 - Issue on DBlinkchange event when object is delete 2025-01-24 11:59:51 +01:00
Stephen Abello
bd93879ac4 Add yellow and purple SCSS variables 2025-01-23 11:27:36 +01:00
Timmy38
133a4a8533 N°8113 Fix global organization filter (#699) 2025-01-23 10:04:02 +01:00
Eric Espie
51bb0add8e Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-22 17:11:13 +01:00
Eric Espie
1163a20cdd Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	application/cmdbabstract.class.inc.php
2025-01-22 16:44:12 +01:00
Eric Espie
a7bc4bd411 Add new measure points for KPI logger 2025-01-22 16:34:31 +01:00
Benjamin Dalsass
6f3fddf9bf N°8122 - View or edit an object in portal in a new tab no more possible 2025-01-22 14:15:23 +01:00
jf-cbd
4c8392b332 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-21 17:43:35 +01:00
jf-cbd
470f145747 N°6284 - fix regex 2025-01-21 17:41:53 +01:00
Timmy38
2852d8ce49 N°7662 Allowing indentation and de-indentation (#698) 2025-01-21 17:12:43 +01:00
jf-cbd
fb180e8370 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-21 17:03:52 +01:00
jf-cbd
7e9a95fe93 Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php
2025-01-21 16:55:04 +01:00
jf-cbd
a07f66c061 Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2025-01-21 16:48:33 +01:00
jf-cbd
c49ceae75e Fix HandleForm call 2025-01-21 16:46:15 +01:00
jf-cbd
2dd1224219 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-21 13:50:19 +01:00
jf-cbd
80244e2797 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-01-21 13:48:12 +01:00
jf-cbd
4da975cb64 Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2025-01-21 12:15:06 +01:00
jf-cbd
8980f627e9 Fix format 2025-01-21 12:09:06 +01:00
jf-cbd
5ce1788d4a N°7776 remove twig from ajax calls, 3.2 edition 2025-01-20 16:34:46 +01:00
jf-cbd
38fe31c9fc Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
2025-01-20 16:33:35 +01:00
jf-cbd
ec61b52238 N°7776 remove twig from ajax calls, 3.1 edition 2025-01-20 16:02:26 +01:00
jf-cbd
072596a53b Merge remote-tracking branch 'origin/support/2.7' into support/3.1
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php
2025-01-20 15:53:34 +01:00
jf-cbd
160bfd714b N°7776 remove twig from ajax calls 2025-01-20 15:41:22 +01:00
Eric Espie
3b51124f1c N°7927 - No context tag available on designer MTP 2025-01-17 10:06:20 +01:00
jf-cbd
e7b87128b1 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-16 17:18:02 +01:00
jf-cbd
19fa836758 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2025-01-16 17:16:31 +01:00
jf-cbd
1c5cb1547f Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2025-01-16 17:15:12 +01:00
jf-cbd
8d58372074 Update unattended installation script documentation 2025-01-16 17:13:26 +01:00
Eric Espie
e98c6637ac N°8108 - EVENT_DB_AFTER_WRITE: $oEventData->Get('changes') missing previous values 2025-01-16 09:31:12 +01:00
odain
7d2a9d0bfc N°8066 - Polishing Webhook Oauth 2025-01-15 17:26:12 +01:00
odain
762d1162ca N°8066 - Polishing Webhook Oauth 2025-01-15 16:59:51 +01:00
odain
d0bdde30ad Merge branch 'support/3.2' into develop 2025-01-14 08:34:41 +01:00
odain
95dbe4c859 N°7873 - ci fix remove useless require_once 2025-01-14 07:52:07 +01:00
Benjamin Dalsass
3fe8b6c696 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-13 15:01:55 +01:00
Benjamin Dalsass
ec6adee9c1 Remove useless require_once and replace it with inheritance 2025-01-13 14:32:06 +01:00
Benjamin Dalsass
baa8bba926 N°8031 - Make all portal bricks use custom templates for all templates
add missing templates
2025-01-13 12:50:58 +01:00
v-dumas
8dc5411717 N°7906 - User Preference: friendlyname, list, search criteria and reconciliation 2025-01-13 12:08:14 +01:00
Tommaso Rossi
6539687f16 🌐 Italian translation enhancements (#697) 2025-01-13 12:07:33 +01:00
Benjamin Dalsass
f1d448fd78 N°8031 - Make all portal bricks use custom templates for all templates
add missing templates
2025-01-13 11:53:44 +01:00
odain
a4490e2b5f N°7873 - Portal: Brick visible despite XML security tag allowed profiles 2025-01-13 11:06:27 +01:00
Eric Espie
e0b12144cb Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	sources/Application/UI/Base/Layout/ActivityPanel/ActivityPanel.php
2025-01-13 09:18:00 +01:00
odain
efb7831a5a N°7111 - False link at the end of the setup 2025-01-13 08:30:23 +01:00
Benjamin Dalsass
9fadbb5eb1 N°8031 - Make all portal bricks use custom templates for all templates (#696)
Service implementation
2025-01-13 08:04:49 +01:00
Romain Quetiez
93dba0644d N°5791 - Handle NOT IN and NOT LIKE too 2025-01-10 16:21:12 +01:00
XGUI
ec324bb28e N°7746 - Caselog edition button active even if the user has a read-only access to the object 2025-01-10 11:12:03 +01:00
Eric Espie
dc8f521b12 N°7145 - UI - Init Value DateTime and Date with Day Time (Add default values on mandatory dates) 2025-01-09 11:56:55 +01:00
Eric Espie
bf6277fcd2 N°7145 - UI - Init Value DateTime and Date with Day Time (support raw date values) 2025-01-09 11:22:28 +01:00
Eric Espie
886db5d6ad N°7145 - UI - Init Value DateTime and Date with Day Time (use OQL syntax for default value) 2025-01-09 10:49:35 +01:00
Eric Espie
79a46581ef Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php
2025-01-07 13:31:49 +01:00
Eric Espie
0e8ddf990c N°7145 - UI - Init Value DateTime and Date with Day Time (Fix Event class) 2025-01-07 13:21:13 +01:00
Eric Espie
346a8eadec N°5791 - Obsolescence condition containing IN makes object creation fail 2025-01-07 11:29:33 +01:00
Eric Espie
6948c594c2 N°7145 - UI - Init Value DateTime and Date with Day Time 2025-01-07 10:18:23 +01:00
Eric Espie
301a7a92a0 N°7145 - UI - Init Value DateTime and Date with Day Time 2025-01-06 16:52:32 +01:00
Eric Espie
73bb80ebea N°7206 - Force DBUpdate() when a transition is asked, and it leads to the same state 2025-01-06 11:31:36 +01:00
Timmy38
1e674d7bdc N°7383 Show data table even when there is no data after filtering (#695) 2025-01-06 11:06:18 +01:00
v-dumas
1225ee1e78 improve test 2025-01-03 17:18:24 +01:00
v-dumas
a91de9fb36 Add helpers for stopwatches manipulation 2025-01-03 17:04:41 +01:00
v-dumas
71b3a415a6 N°7206 - Add tests 2025-01-03 16:17:51 +01:00
Romain Quetiez
b97c7433c8 🎨 N°7633 Cosmetics on unit tests 2025-01-03 11:57:51 +01:00
jf-cbd
5a59d16c99 Merge remote-tracking branch 'origin/support/3.2' into develop 2025-01-02 09:34:32 +01:00
jf-cbd
11fc958a7b 🐛 N°6284 - Add data-object-key 2024-12-31 15:01:36 +01:00
odain
a63a3d3d9c Merge branch 'support/3.2' into develop 2024-12-27 11:14:21 +01:00
odain
a151e40b75 Merge branch 'support/3.1' into support/3.2 2024-12-27 11:13:50 +01:00
odain
5780f26817 N°7810: fix merge 2024-12-27 11:13:31 +01:00
odain
ed6e4f612a Merge branch 'support/3.2' into develop 2024-12-27 09:24:49 +01:00
odain
9a690861a3 Merge branch 'support/3.1' into support/3.2 2024-12-27 09:24:33 +01:00
odain
343f3286b8 Merge branch 'support/2.7' into support/3.1 2024-12-27 09:08:47 +01:00
Eric Espie
37fc1a5723 N°7810 - security hardening 2024-12-27 09:04:28 +01:00
Eric Espie
16279233e0 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-26 14:54:14 +01:00
Eric Espie
7a09b3effc 🐛 Don't display create mailbox if the corresponding class does not exist 2024-12-24 15:05:48 +01:00
Romain Quetiez
4f6d514694 N°8001 - Refactoring: instantiation of an ormDocument moved to... ormDocument 2024-12-20 10:36:25 +01:00
Stephen Abello
07964cc404 Merge branch 'support/3.2' into develop 2024-12-20 10:16:11 +01:00
Stephen Abello
8f8b65a71d N°8031 - Add robustness if portal configuration doesn't go through 2024-12-20 10:15:22 +01:00
Timothee
49e72e83fe N°6282 Fix XSS vulnerability in wsdl 2024-12-19 15:34:43 +01:00
Stephen Abello
ea5473ad77 Merge branch 'support/3.2' into develop 2024-12-19 15:16:51 +01:00
Stephen Abello
f0685e33e1 N°8031 - Add robustness and fix SF parameter binding being ambiguous in extensions bricks 2024-12-19 15:14:46 +01:00
Tommaso Rossi
2a888cf5af 🌐 Update IT IT dictionaries (#693) 2024-12-19 14:13:13 +01:00
Timmy38
42f391472b N°6282 Fix XSS vulnerability in soap (#690)
* N°6282 Fix XSS vulnerability in soap
2024-12-19 11:39:00 +01:00
Eric Espie
30ef2735b6 N°8001 - TriggerOnObjectMention : load of the icon failed 2024-12-18 16:03:39 +01:00
Stephen Abello
548131482a Merge branch 'support/3.2' into develop 2024-12-18 11:10:43 +01:00
Stephen Abello
bbff0b72d3 N°8031 - Make all portal bricks use custom templates for all templates (#691)
* N°8031 - Make all portal bricks use custom templates for all templates

* Rename parameter following code review

* Add const variables following code review

* Modify method name following code review
2024-12-18 11:09:39 +01:00
Stephen Abello
5ac6c84813 N°8031 - Make all portal bricks use custom templates for all templates (#691)
* N°8031 - Make all portal bricks use custom templates for all templates

* Rename parameter following code review

* Add const variables following code review

* Modify method name following code review
2024-12-18 11:03:52 +01:00
jf-cbd
0c3a35fc43 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-18 10:49:22 +01:00
jf-cbd
2dffab9ca0 🌐 Update ZH CN dictionaries 2024-12-18 10:39:25 +01:00
jf-cbd
881dbd3c01 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-18 10:12:13 +01:00
jf-cbd
1cbfa4f1b1 🌐 Update ZH CN dictionaries 2024-12-18 10:11:52 +01:00
jf-cbd
81887f480a 🌐 Update ZH CN dictionaries 2024-12-18 10:08:55 +01:00
odain
d25bf4ef66 Merge branch 'support/3.2' into develop 2024-12-17 17:32:17 +01:00
odain-cbd
5f85757630 N°7633 - Reloads the same user multiple times if it no longer exists (#692)
* N°7633 - Reloads the same user multiple times if it no longer exists

* Update core/userrights.class.inc.php

good catch

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

* Update core/userrights.class.inc.php

good catch (again)

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

* Update core/userrights.class.inc.php

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

* PR feedbacks from Romain

* ci: rename user logins

---------

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
2024-12-17 17:27:49 +01:00
jf-cbd
90f58721b1 🌐 Update ZH CN dictionaries 2024-12-17 17:21:55 +01:00
v-dumas
56d3ac668c N°8047 - SuperUser profile moved under iTop Community 3.2.1 2024-12-17 16:31:59 +01:00
Eric Espie
b20b4b7e82 Revert GetDataPath() usage 2024-12-17 15:53:57 +01:00
jf-cbd
eeabad895d 🌐 Update EN dic 2024-12-16 18:48:48 +01:00
jf-cbd
9fdf183851 Merge branch 'support/3.2' into develop
# Conflicts:
#	dictionaries/ui/components/quick-create/zh_cn.dictionary.itop.quick-create.php
#	dictionaries/zh_cn.dictionary.itop.core.php
#	setup/runtimeenv.class.inc.php
2024-12-16 18:38:07 +01:00
jf-cbd
0a3b02bf45 🌐 Update ZH CN dictionaries 2024-12-16 18:30:22 +01:00
jf-cbd
74ebbc5fa4 🌐 Update ZH CN dictionaries 2024-12-16 18:19:17 +01:00
Eric Espie
a762b6a2bb Fix failing directory removal 2024-12-16 17:04:33 +01:00
Eric Espie
32ef639ce1 N°7803 - MTP from itophub/designer failing in itop 3.2.0 2024-12-16 16:44:59 +01:00
Purple Grape
8647a76dbf 🌐 Translations - improved translation for zh cn 20241108 (#679)
* improved translation for zh cn
2024-12-16 11:39:26 +01:00
jf-cbd
96414dcc98 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-16 11:07:32 +01:00
jf-cbd
47cd8bce31 Security hardening 2024-12-16 11:05:16 +01:00
jf-cbd
86c677b2ca Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php
2024-12-16 11:02:37 +01:00
Eric Espie
960129316d N°8050 - Fix regression due to directories filter changes 2024-12-16 10:56:06 +01:00
jf-cbd
1fa50f695d Security hardening 2024-12-16 10:47:06 +01:00
Anne-Cath
6ab19d29b9 fix tests in all iTop configurations 2024-12-16 10:38:44 +01:00
jf-cbd
692cf4f635 Merge branch 'support/2.7' into support/3.1 2024-12-16 10:27:00 +01:00
jf-cbd
95aa444ee6 Security hardening 2024-12-13 16:48:13 +01:00
jf-cbd
f5de808c7c Security hardening (#685)
* security hardening
2024-12-13 15:09:18 +01:00
Eric Espie
5c5c5d769f Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-13 10:17:40 +01:00
Eric Espie
fc388313d7 N°8050 - Problems with interface discovery from itop 2024-12-13 10:14:17 +01:00
odain
d544ee5498 N°7750 - ci enhance test 2024-12-13 09:35:35 +01:00
Anne-Cath
ecce0a3376 fix tests 2024-12-13 09:20:19 +01:00
odain
ce187550f6 N°7750 - Fix display regression 2024-12-12 12:21:57 +01:00
Anne-Cath
f8e761abe0 fix tests 2024-12-12 11:45:09 +01:00
Eric Espie
d3a9e30178 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-12 09:55:58 +01:00
Eric Espie
5d15a08824 🥅 Fast setup error display 2024-12-12 09:55:16 +01:00
Eric Espie
0fd2cf85a2 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-12 08:44:38 +01:00
odain
8135316119 N°7750 - Bug with OQL set as Shortcut 2024-12-11 16:05:15 +01:00
Eric Espie
868c0ae836 N°7997 - Sharing Base incompatible with iTop >= 3.1 (code review) 2024-12-11 15:51:36 +01:00
Eric Espie
d03d4fce5f N°7997 - Sharing Base incompatible with iTop >= 3.1 2024-12-11 13:35:15 +01:00
Eric Espie
aa55c2b30f N°7997 - Sharing Base incompatible with iTop >= 3.1 2024-12-11 13:28:37 +01:00
Eric Espie
9d3b46b919 🥅 Fast setup error display 2024-12-11 11:40:03 +01:00
Eric Espie
01b4dbba71 🥅 Fast setup error display 2024-12-11 11:20:32 +01:00
Eric Espie
72ac4096c1 N°7854 - ⬆️ Bump twig version 2024-12-10 17:08:48 +01:00
Eric Espie
19559b08a7 N°7854 - ⬆️ Bump twig version 2024-12-10 10:52:30 +01:00
Eric Espie
346564ca0e N°7854 - ⬆️ Bump twig version 2024-12-10 10:11:28 +01:00
Anne-Cath
a64fed66a3 N°1681 - Add/fix @since 2024-12-10 09:48:25 +01:00
Anne-Catherine
261106fa9d N°1681 - Add new triggers for attachment creation and removal (#534) 2024-12-10 09:33:20 +01:00
Eric Espie
1556b95653 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-09 17:06:40 +01:00
Eric Espie
1bf53bae2a N°7871 - unable to migrate to itop3.2 if a trigger on object mention without "mentioned filter" exists 2024-12-09 17:05:07 +01:00
Anne-Catherine
324cb5eb6c N°7636 - Too many OQL requests executed in order to display a lnk (#661) 2024-12-09 15:15:33 +01:00
Timmy38
eedbf3d266 N°6617 Fix issue when providing invalid dashboard layout class (#689)
N°6617 Fix issue when providing invalid dashboard layout class
2024-12-09 14:10:03 +01:00
Eric Espie
3b197692ec Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-09 10:40:06 +01:00
Eric Espie
29ce042916 N°7867 - Issue with MTP offline (reset cache in metamodel) 2024-12-09 10:38:50 +01:00
odain
83539d6d4c N°7446 - Make ItopCustomDatamodelTestCase work with modules in production-modules 2024-12-05 11:29:05 +01:00
Eric Espie
e6a7b926f6 N°7852 - Issue on Class groups definition when checking EventNotification class 2024-12-05 11:14:19 +01:00
Eric Espie
b30e053236 N°8020 - Bugs MFA and designer incompatibility 2024-12-03 16:42:27 +01:00
Stephen Abello
ecfc26f1ec Merge branch 'support/3.2' into develop 2024-12-03 10:47:42 +01:00
Stephen Abello
afd96a0f49 N°7995 - Allow to redefine portal twig template for all bricks in a portal (#686)
* N°7995 - Allow to redefine portal twig template for all bricks in a portal

* Apply modifications from code review

* Fix variable name

* Apply changes from code review
2024-12-03 10:44:37 +01:00
Stephen Abello
a34baf840a N°7995 - Allow to redefine portal twig template for all bricks in a portal (#686)
* N°7995 - Allow to redefine portal twig template for all bricks in a portal

* Apply modifications from code review

* Fix variable name

* Apply changes from code review
2024-12-03 10:41:25 +01:00
Eric Espie
6f9bd9bae5 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-12-03 10:31:35 +01:00
Eric Espie
a77765ec7b N°8019 - Enrich event with transition information 2024-12-03 10:28:13 +01:00
jf-cbd
64b4b03ea9 Security hardening 2024-12-03 10:26:11 +01:00
XGUI
c32b2f9dfe Issue/7984 (#688)
* N°7984 - Change ? for field description (tooltip) by 🛈 in console and portal
2024-12-03 10:20:47 +01:00
jf-cbd
a797878b17 Security hardening 2024-12-03 09:54:31 +01:00
jf-cbd
a1860c82fb Merge branch 'support/3.2' into develop 2024-12-02 17:47:10 +01:00
jf-cbd
1fa0f7bdd9 N°8007 - Security hardening 2024-12-02 17:45:39 +01:00
Eric Espie
f718b4173d N°7206 - TriggerOnStateEnter not called when using reassign transition (after review) 2024-12-02 17:28:15 +01:00
Eric Espie
e057c0f081 N°7777 - Click on tab "Last executions" during action creation crashs the form 2024-12-02 17:12:32 +01:00
Eric Espie
5a49fc7654 N°7206 - TriggerOnStateEnter not called when using reassign transition 2024-12-02 14:49:28 +01:00
Stephen Abello
6fca659c9d Fix portal not being able to use $common-* SCSS variables when recompiling stylesheets 2024-12-02 14:06:53 +01:00
Stephen Abello
eacd08f31e Fix SCSS comments type 2024-12-02 14:03:39 +01:00
jf-cbd
d47d65df10 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-11-29 16:49:57 +01:00
jf-cbd
5f7d8f6cc0 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-11-29 16:43:13 +01:00
jf-cbd
cbb4281a37 N°7980 - security hardening 2024-11-29 16:40:34 +01:00
XGUI
b42297ad84 Merge branch 'issue/7726' into develop
# Conflicts:
#	core/datamodel.core.xml
2024-11-29 16:28:50 +01:00
XavierGR
6cb1cf7b7e N°7726 - Fatal error if a newsroom is sent without any message 2024-11-29 16:26:32 +01:00
odain
d7a8d335d5 N°7446 - Fix in CI environment when class already loaded 2024-11-29 12:22:38 +01:00
odain
a65dd1c27c Merge branch 'support/3.2' into develop 2024-11-29 12:09:08 +01:00
odain
bd1d447677 N°7446 - Fix in CI environment 2024-11-29 12:08:16 +01:00
XGUI
d85d611642 Merge branch 'feature/5874' into develop 2024-11-29 08:38:52 +01:00
XavierGR
6a00786535 N° 5874 - Quick create: improvement for newcomer 2024-11-29 08:37:11 +01:00
XGUI
6490fe93a1 Merge branch 'issue/7746' into develop 2024-11-29 08:24:27 +01:00
xavier.guiboud-ribaud@combodo.com
642a13ad0d N°7984 - Change ? for field description (tooltip) by 🛈 in console and portal 2024-11-29 08:23:40 +01:00
xavier.guiboud-ribaud@combodo.com
e1bfe9a3b6 * N°7746 - Caselog edition button active even if the user has a read-only access to the object 2024-11-29 08:23:32 +01:00
XGUI
af8ff9b29f Issue/7707 (#687)
* N°7707 - Newsroom user preference display counter not changeable
2024-11-28 16:02:35 +01:00
Eric Espie
bb405d5173 N°7429 - Create an MFA extension for iTop - Add support for AttributeClassSet 2024-11-27 14:57:51 +01:00
Benjamin Dalsass
fcfdac2844 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-11-27 09:56:35 +01:00
Benjamin Dalsass
4723fc885c Merge remote-tracking branch 'origin/support/3.1' into support/3.2
# Conflicts:
#	application/dashboard.class.inc.php
2024-11-27 09:55:15 +01:00
Benjamin Dalsass
06dcae1dd1 Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2024-11-27 09:50:57 +01:00
Benjamin Dalsass
e03033ce52 N°7219 - Fatal error following dashboard modification when dashboard title contains an é 2024-11-27 09:40:22 +01:00
Timothee
19eae916f0 N°7792 Do not initialize CAS if already started 2024-11-22 09:59:41 +01:00
Romain Quetiez
ce68e270c3 N°7985 Remove OQL grammar ambiguity leading to scary warnings when generating the parser (4 parsing conflicts) 2024-11-21 10:29:45 +01:00
jf-cbd
0d8a20c35e Merge remote-tracking branch 'origin/support/3.2' into develop 2024-11-19 08:50:29 +01:00
Lars Kaltefleiter
596e26a96f 🌐 N°7932 Translations - British English (#677)
* Translation into EN GB
2024-11-18 14:38:53 +01:00
Thomas Casteleyn
1f3780f338 Correctly identify as iTop in cURL requests (#652)
* Correctly identify as iTop in cURL requests (with configuration option)
2024-11-14 15:18:47 +01:00
Eric Espie
85f6195a51 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-11-14 14:34:05 +01:00
Thomas Casteleyn
7e1b1779a9 ️ Add faster way to rename column on the same table (#676)
* Add faster way to rename column on the same table
2024-11-14 14:24:45 +01:00
Eric Espie
ef42a49009 Allow extensions to add extra datamodel for tests 2024-11-14 09:27:57 +01:00
Romain Quetiez
51e5f1e7de N°7962 Suppress warnings emitted by the parser/lexer generators and the runtime OQL lexer, with PHP 8.1+ 2024-11-13 15:28:29 +01:00
Timothee
9cffd17e19 N°7704 Fix missing namespace for constant EVENT_DOWNLOAD_DOCUMENT 2024-11-13 14:39:23 +01:00
Benjamin Dalsass
d95e7168aa Merge branch 'support/3.2' into develop 2024-11-13 13:32:53 +01:00
Benjamin Dalsass
e9f16935b6 N°6613 - Fix user picture pushing invalid data 2024-11-13 13:20:27 +01:00
Timothee
e7488b2c89 N°7721 default configuration parameter 2024-11-12 14:48:58 +01:00
Stephen Abello
8ac4086e71 N°7793 Fix primary color being set to blue due to a mistake 2024-11-12 13:52:03 +01:00
Benjamin Dalsass
6b5273fa1c N°1000 - Portal: filter BrowseBrick result varies if in list or tree (#673)
* N°1000 - Portal: filter BrowseBrick result varies if in list or tree

* N°1000 - Portal: filter BrowseBrick result varies if in list or tree
- replace html separators by css class

* N°1000 - Portal: filter BrowseBrick result varies if in list or tree
- replace html separators by css class

* N°1000 - Portal: filter BrowseBrick result varies if in list or tree
- add alteration comment to Tree List Filter jQuery plugin 1.0
- remove display none to tree-item-filter-data
2024-11-12 11:02:43 +01:00
jf-cbd
a7c22c06af Merge remote-tracking branch 'origin/support/3.2' into develop 2024-11-12 09:37:41 +01:00
jf-cbd
9b1e854bf7 Update translations 2024-11-12 09:27:35 +01:00
denis.flaven@combodo.com
a72d1ca1b3 🔨 Replace gitmojis by their UTF-8 equivalent in output. 2024-11-08 16:08:06 +01:00
Lars Kaltefleiter
926700856d Fix some typos in en translations (#678) 2024-11-08 10:56:10 +01:00
Stephen Abello
be5e4458ba N°7793 Add breaking changes introduced by adding common SCSS variables between backoffice and end-user portal (#675)
* N°7793 Add breaking changes induce by adding common SCSS variables between backoffice and end-user portal

* N°7793 Handle breaking changes in darkmoon theme
2024-11-08 10:04:56 +01:00
Stephen Abello
317cd585b2 Merge branch 'support/3.2' into develop 2024-11-08 09:45:05 +01:00
Stephen Abello
ab93d59a77 Merge branch 'support/3.1' into support/3.2
# Conflicts:
#	sources/Core/Email/EmailLaminas.php
2024-11-08 09:41:48 +01:00
Karel Vlk
c70d62a51e 🐛 N°7916 SF#2274 EmailLaminas.php: Keep charset with part header in multipart email (#672)
* 🐛 N°2274 EmailLaminas.php: Keep charset with part header in multipart email

* Add a unit test

---------

Co-authored-by: Stephen Abello <stephen.abello@combodo.com>
2024-11-08 09:38:57 +01:00
jf-cbd
5d8db176f4 Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	dictionaries/es_cr.dictionary.itop.core.php
2024-11-07 14:57:54 +01:00
jf-cbd
82bc2f33f2 Merge remote-tracking branch 'origin/support/3.1' into support/3.2 2024-11-07 14:53:48 +01:00
jf-cbd
0d5ff261fe Merge remote-tracking branch 'origin/support/2.7' into support/3.1 2024-11-07 14:51:32 +01:00
jf-cbd
374b35f78a 🚀 Fix GitHub action 2024-11-07 14:50:46 +01:00
Eric Espie
f5c29edee4 N°7874 - Inline image deleted by garbage collector 2024-11-07 09:24:33 +01:00
Timothee
8fb450a6d4 🌐 ES localization, Fix encoding 2024-11-06 17:37:37 +01:00
Timothee
311c5d0d51 🌐 ES localization 2024-11-06 17:12:47 +01:00
Stephen Abello
c6039f4b51 Merge branch 'support/3.2' into develop 2024-11-06 09:57:03 +01:00
Stephen Abello
f90bd81e15 N°7793 Add common SCSS variables between backoffice and end-user portal (#674)
* N°7793 Add common SCSS variables between backoffice and end-user portal

* Add shame & readme

* Move font face to common

* Inherit color functions

* Move font icon to common

* FIx breaking change introduced in lifecycle palette

* FIx breaking change introduced in base

* Move approot url to common

* Make highlightjs common variables more coherent with 3.2.1 commonization approach

* Deprecated and migrate the usage of ibo-adjust-alpha and ibo-adjust-lightness
2024-11-06 09:52:54 +01:00
Stephen Abello
a10e547420 N°7898 CKEditor content should be inserted at the cursor position. Thanks to @jbostoen 2024-11-04 15:57:44 +01:00
Stephen Abello
d0f9e57bf1 Merge branch 'support/3.2' into develop 2024-11-04 14:40:52 +01:00
Stephen Abello
2519456c98 Merge branch 'support/3.1' into support/3.2 2024-11-04 14:39:37 +01:00
Stephen Abello
9371bc6d7b N°7925 Fix incorrectly formatted In-Reply-To email header 2024-11-04 14:38:31 +01:00
Karel Vlk
58e964fb8c 🐛 N°7917 SF#2272 EmailLaminas.php: Fix Message-ID format (#671)
* 🐛 N°2272 EmailLaminas.php: Fix Message-ID format

* EmailLaminas.php: Add MessageId import

as suggested by @steffunky in PR 671
2024-11-04 14:37:15 +01:00
v-dumas
57760528c9 N°7759 - Improve Delivery Model Tooltips 2024-11-04 12:21:17 +01:00
jf-cbd
385c60e993 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-10-31 09:41:38 +01:00
Eric Espie
58c68bade9 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-10-29 11:18:45 +01:00
Anne-Cath
eb992c7b45 N°7915 - declaration of DisplayBareProperties function in DocumentFile class has wrong id 2024-10-25 15:40:43 +02:00
Anne-Catherine
0688405f86 N°7348 - Enable to param maximum depth of impact analysis in function Ticket::UpdateImpactedItems (#633) 2024-10-25 15:29:09 +02:00
jf-cbd
dd34fda42e Merge remote-tracking branch 'origin/support/3.2' into develop 2024-10-23 17:56:09 +02:00
jf-cbd
6becd73ac2 Update tests to be minimal and removed hard-coded ITOP_DESIGN_LATEST_VERSION VERSION 2024-10-22 11:47:25 +02:00
jf-cbd
72d6e251b8 🔖 Update tests for XML 3.3.0 version 2024-10-21 18:39:39 +02:00
jf-cbd
9491c9102c 🔖 Update tests for XML 3.3.0 version 2024-10-21 18:28:50 +02:00
jf-cbd
a728cf312d 🔖 Update XML 3.3.0 version 2024-10-21 18:21:37 +02:00
jf-cbd
e321e27899 🔖 Prepare 3.3.0 version 2024-10-21 18:07:54 +02:00
jf-cbd
96e8467e13 Temporary rollback : waiting for datamodel upgrade 2024-10-21 18:01:58 +02:00
jf-cbd
508918a684 Temporary rollback : waiting for datamodel upgrade 2024-10-21 17:56:43 +02:00
jf-cbd
8adef26d18 🔖 Prepare 3.3.0 version 2024-10-21 17:36:45 +02:00
jf-cbd
2d45abd12b 🔖 Prepare 3.3.0 version 2024-10-21 17:34:30 +02:00
jf-cbd
bd5e55aad9 🔖 Prepare 3.3.0 version 2024-10-21 17:26:15 +02:00
Eric Espie
b57e4fce07 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-10-14 09:27:25 +02:00
jf-cbd
b460705831 Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	.doc/itop-version-history.md
2024-09-30 11:46:20 +02:00
Eric Espie
58c47f4c0a Merge remote-tracking branch 'origin/support/3.2' into develop 2024-09-26 17:41:05 +02:00
Anne-Catherine
f3a6b064c8 N°824 - Allow OQL JOIN on object ON EventNotification (#642) 2024-09-19 08:58:27 +02:00
Anne-Cath
5e6fb33ed7 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-09-19 08:11:56 +02:00
Anne-Cath
5e7137e0c4 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-09-19 07:51:37 +02:00
BenGrenoble
4cf5e47ec3 N°7796 - itop-ticket and itop-bridge-cmdb-ticket not coherents 2024-09-18 16:06:06 +02:00
Anne-Cath
143a59a19d Merge remote-tracking branch 'origin/support/3.2' into develop 2024-09-18 11:59:16 +02:00
Eric Espie
61b247b156 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-09-11 17:34:34 +02:00
Molkobain
c1aa013053 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-09-06 11:59:46 +02:00
Benjamin Dalsass
a3f9eed6e2 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-08-20 16:55:11 +02:00
jf-cbd
21c9332a7f Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-08-07 18:01:38 +02:00
Benjamin Dalsass
ae6e0a08ea Merge remote-tracking branch 'origin/support/3.2' into develop 2024-08-07 08:33:27 +02:00
Benjamin Dalsass
d9d2e851f4 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-08-07 07:57:33 +02:00
Molkobain
91c63cb12e Merge remote-tracking branch 'origin/support/3.2' into develop 2024-08-05 17:28:36 +02:00
Molkobain
4ff354dd41 Update itop-version-history.md 2024-07-29 10:04:48 +02:00
Molkobain
bd8c325306 📝 Fix version history 2024-07-29 10:02:08 +02:00
Molkobain
9902cedc06 📝 Update version history 2024-07-29 09:56:52 +02:00
Molkobain
b64ee96636 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-29 09:56:15 +02:00
Molkobain
8c1ff2dc1c Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-25 10:53:55 +02:00
Molkobain
f2ab409c9c Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-25 08:32:28 +02:00
Molkobain
db46763e13 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-24 11:02:36 +02:00
Molkobain
7ee1af3cc8 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-24 10:58:05 +02:00
Timothee
32b371eac1 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-16 09:57:16 +02:00
Benjamin Dalsass
f65cadd24c Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-15 10:59:01 +02:00
jf-cbd
40551b36e5 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-07-12 10:40:09 +02:00
Molkobain
c0056e75d0 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-10 11:39:14 +02:00
jf-cbd
e5825b5fcd Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-07-05 14:06:00 +02:00
Benjamin Dalsass
d3dc59c5da Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-05 09:25:53 +02:00
Molkobain
642a097b4b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-05 00:19:17 +02:00
jf-cbd
1c615c42b6 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-07-04 13:56:53 +02:00
jf-cbd
b1f708dcad Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-07-04 11:01:53 +02:00
Benjamin Dalsass
55f202b7cb Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-04 07:57:38 +02:00
jf-cbd
247f1045fe Merge branch 'refs/heads/support/3.2' into develop 2024-07-03 15:52:49 +02:00
jf-cbd
42e78ad3a3 Merge branch 'refs/heads/support/3.2' into develop 2024-07-02 17:21:43 +02:00
odain
113826b2e7 Merge branch 'support/3.2' into develop 2024-07-02 17:13:30 +02:00
odain
7fe8da8590 Merge branch 'support/3.2' into develop 2024-07-02 14:10:54 +02:00
Eric Espie
821251a53f Merge remote-tracking branch 'origin/support/3.2' into develop 2024-07-02 10:43:23 +02:00
Molkobain
5334bbb303 Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	.doc/itop-version-history.md
2024-06-28 15:08:31 +02:00
Eric Espie
012d5e7ae0 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-24 14:36:53 +02:00
Eric Espie
03f4e9f621 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-20 11:08:59 +02:00
Romain Quetiez
055968bea9 Update README.md 2024-06-17 14:40:31 +02:00
Romain Quetiez
d0457b73ec Merge branch 'refs/heads/support/3.2' into develop 2024-06-13 18:52:40 +02:00
jf-cbd
7e8ff50886 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop
# Conflicts:
#	js/ckeditor/src/plugins/maximize/maximize.plugin.ts
2024-06-13 17:53:06 +02:00
Eric Espie
36a6ee4fc9 Merge remote-tracking branch 'origin/feature/3.2-post-beta' into develop 2024-06-12 16:50:02 +02:00
Benjamin Dalsass
db8b00e8df Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-10 16:15:20 +02:00
Benjamin Dalsass
5d31c372fa Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-10 10:08:11 +02:00
Benjamin Dalsass
0497122e25 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-07 08:55:30 +02:00
Benjamin Dalsass
645d68d5d0 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-07 08:20:40 +02:00
Romain Quetiez
f04b8368aa List explicitely the modules when finding inconsistencies in installation.xml 2024-06-04 21:58:18 +02:00
vdumas
f9fd4f1e2a N°6303 - Add search ticket bricks in portal 2024-06-04 21:58:18 +02:00
Benjamin Dalsass
55ed552ba7 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-04 10:59:39 +02:00
Benjamin Dalsass
7bfa23fab7 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-06-03 15:51:14 +02:00
Eric Espie
7bd427b4e7 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-30 12:08:40 +02:00
Benjamin Dalsass
a9a9fb1da2 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-30 09:21:58 +02:00
Eric Espie
6653b13144 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-29 18:21:06 +02:00
Benjamin Dalsass
8bea29f0e7 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-28 16:07:36 +02:00
Benjamin Dalsass
d556564ee1 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-28 08:31:18 +02:00
Benjamin Dalsass
2286a9e2a4 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-28 08:17:19 +02:00
Molkobain
30c10cb67f Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-24 23:58:32 +02:00
Benjamin Dalsass
74a42a4d4f Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-24 16:14:44 +02:00
Eric Espie
c31443cb79 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-24 10:18:48 +02:00
Eric Espie
a698aec7a5 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-21 15:08:32 +02:00
Eric Espie
04d2aaf05c Merge remote-tracking branch 'origin/support/3.2' into develop 2024-05-21 14:30:30 +02:00
jf-cbd
5103f898e1 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-05-17 11:23:08 +02:00
Romain Quetiez
68ee3231f4 Merge branch 'support/3.2' into develop
# Conflicts:
#	tests/php-unit-tests/src/Hook/TestsRunStartHook.php
2024-05-16 20:24:38 +02:00
jf-cbd
62a7850a0b Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-04-30 15:12:21 +02:00
jf-cbd
20f1ec42b1 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-04-30 10:58:35 +02:00
jf-cbd
e51e55b634 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop
# Conflicts:
#	pages/ajax.render.php
2024-04-30 08:18:57 +02:00
Benjamin Dalsass
bc7db973ad Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-25 09:17:33 +02:00
jf-cbd
0489103e11 Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-04-24 17:13:36 +02:00
Eric Espie
b99249d2d2 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-24 16:11:58 +02:00
jf-cbd
23aed5415c Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop 2024-04-23 15:24:52 +02:00
jf-cbd
2adbcf5e6f Merge remote-tracking branch 'refs/remotes/origin/support/3.2' into develop
# Conflicts:
#	pages/ajax.render.php
2024-04-19 15:37:52 +02:00
jf-cbd
6a99e3c1c9 Revert "Merge branch 'refs/heads/support/3.2' into develop"
This reverts commit 8e1de5bf2d, reversing
changes made to f6808ee522.
2024-04-19 15:34:56 +02:00
jf-cbd
8e1de5bf2d Merge branch 'refs/heads/support/3.2' into develop 2024-04-19 11:28:55 +02:00
Molkobain
f6808ee522 Fix typo in README.md 2024-04-19 11:22:33 +02:00
Molkobain
4f650d3c5b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-19 09:26:10 +02:00
Molkobain
ba641d96d5 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-18 18:51:05 +02:00
Molkobain
3dc514c67d Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-18 18:19:52 +02:00
Molkobain
5df7c58b1b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-18 17:03:24 +02:00
Benjamin Dalsass
bb680ac514 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-17 16:05:56 +02:00
Stephen Abello
e18018cacd Merge branch 'support/3.2' into develop 2024-04-16 09:22:58 +02:00
odain
5d91c8832b Merge branch 'support/3.2' into develop 2024-04-15 10:25:01 +02:00
odain
c96c8ac30d Merge branch 'support/3.2' into develop 2024-04-12 17:19:45 +02:00
Molkobain
f930533d8b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-12 11:08:59 +02:00
odain
29bfb8a8bf Merge branch 'support/3.2' into develop 2024-04-11 18:56:02 +02:00
Molkobain
f04359f398 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-11 17:04:13 +02:00
odain
c24052e976 Merge branch 'support/3.2' into develop 2024-04-10 15:35:17 +02:00
odain
5f8e43fc67 Merge branch 'support/3.2' into develop 2024-04-10 14:26:43 +02:00
jf-cbd
5427b146cf Merge branch 'refs/heads/support/3.2' into develop 2024-04-10 10:36:40 +02:00
odain
6f231ce800 Merge branch 'support/3.2' into develop 2024-04-09 21:37:20 +02:00
odain
d66d1c8739 Merge branch 'support/3.2' into develop 2024-04-09 11:07:21 +02:00
odain
50b4388b8d Merge branch 'support/3.2' into develop 2024-04-09 11:02:32 +02:00
odain
9cc8b75ffb Merge branch 'support/3.2' into develop
# Conflicts:
#	setup/applicationinstaller.class.inc.php
2024-04-09 10:13:45 +02:00
jf-cbd
e715342f7a Merge branch 'refs/heads/support/3.2' into develop 2024-04-08 17:26:40 +02:00
jf-cbd
c86ac4f9a7 Merge branch 'refs/heads/support/3.2' into develop 2024-04-08 17:13:34 +02:00
Molkobain
b79fe06be4 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-08 15:14:30 +02:00
jf-cbd
e5764ac495 Merge branch 'refs/heads/support/3.2' into develop 2024-04-08 14:14:31 +02:00
Molkobain
2ff7cb8956 Add Vincenzo Katriel Giuva (@DarkNight97boss) to the contributors list! 🙌 2024-04-05 16:18:52 +02:00
jf-cbd
3064ab4b25 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-05 15:01:41 +02:00
Molkobain
d2f8d2e903 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-04 15:22:25 +02:00
odain
036c7796e5 Merge branch 'support/3.2' into develop 2024-04-02 15:08:29 +02:00
Molkobain
356dd46537 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-02 10:40:57 +02:00
Molkobain
bb30e1abb8 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-04-02 10:29:30 +02:00
Stephen Abello
84d225e389 Merge branch 'support/3.2' into develop 2024-03-29 11:20:07 +01:00
Eric Espie
dcf2780cac Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-28 13:33:04 +01:00
Eric Espie
3e421c770b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-27 11:30:02 +01:00
Anne-Cath
19cb0e873a Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-26 11:41:26 +01:00
Molkobain
ed81dbc4a2 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-21 17:43:41 +01:00
Eric Espie
a93d5b87e1 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-19 17:16:35 +01:00
Molkobain
d40a52e403 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-19 14:55:15 +01:00
Eric Espie
a4a3797cc1 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-19 14:07:55 +01:00
Pierre Goiffon
bd29e5f13a Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-18 18:20:19 +01:00
Pierre Goiffon
ce13ee8a55 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-18 18:17:20 +01:00
Pierre Goiffon
e5ed5fbc6a Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-14 17:28:11 +01:00
jf-cbd
ff7eca2f08 Merge branch 'support/3.2' into develop
# Conflicts:
#	lib/composer/installed.php
2024-03-14 17:17:55 +01:00
Pierre Goiffon
06be217030 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-13 10:08:40 +01:00
Pierre Goiffon
4880052559 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-13 09:28:07 +01:00
Pierre Goiffon
147043857b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-12 18:39:44 +01:00
Pierre Goiffon
1bfa1a7746 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-12 17:44:49 +01:00
Benjamin Dalsass
3747a6a454 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-12 09:48:37 +01:00
Pierre Goiffon
f1e6246962 N°7299 Remove moment.js (moved to NPM) 2024-03-11 16:56:41 +01:00
Pierre Goiffon
d2c6190b59 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-11 16:40:49 +01:00
Pierre Goiffon
0f8247ce69 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-11 16:32:03 +01:00
Benjamin Dalsass
dae3be99ce Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-11 16:05:34 +01:00
Pierre Goiffon
6e625e0cc9 N°7329 remove js/jquery.autocomplete.js 2024-03-08 16:19:29 +01:00
Pierre Goiffon
a602101695 Merge remote-tracking branch 'origin/support/3.2' into develop
# Conflicts:
#	js/jquery-ui-1.11.4.custom.min.js
#	js/jquery-ui.custom.min.js
2024-03-08 16:16:18 +01:00
Pierre Goiffon
48d86fdbf5 N°4797 Remove js/jquery-ui-1.11.4.custom.min.js
File was deprecated in 3.0.0 with N°3184
Use instead JQuery lib in NPM (since 3.2.0 N°5621)
2024-03-08 12:47:14 +01:00
Pierre Goiffon
d6cfde0f94 N°7299 Remove jquery-migrate (moved to NPM) 2024-03-07 15:33:07 +01:00
Pierre Goiffon
1b9b4fdd39 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-07 15:28:27 +01:00
Benjamin Dalsass
8bb551eb10 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-07 14:34:20 +01:00
Molkobain
6177035f84 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-07 13:26:29 +01:00
Pierre Goiffon
e6d3ce5918 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-07 11:12:39 +01:00
Molkobain
9e08143981 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-06 14:47:29 +01:00
Pierre Goiffon
2014a48d22 N°7299 Remove CSS & JS files moved to NPM
Migration was made in 3.2 with N°5621
2024-03-04 11:19:59 +01:00
Pierre Goiffon
b7e1202cf1 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-04 10:43:16 +01:00
Pierre Goiffon
44b994414d Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-04 08:42:18 +01:00
Pierre Goiffon
a7265c2493 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-01 17:26:55 +01:00
jf-cbd
261ec270c5 ✏️ fix a typo 2024-03-01 17:24:39 +01:00
Eric Espie
356be511a8 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-03-01 09:44:24 +01:00
Anne-Cath
f896e72013 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-29 16:57:24 +01:00
Benjamin Dalsass
187a895265 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-28 17:16:55 +01:00
Pierre Goiffon
6224f8ca51 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-28 16:44:29 +01:00
Pierre Goiffon
3b27e6e466 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-28 15:13:06 +01:00
Anne-Cath
4e53deec9d Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-28 10:37:15 +01:00
Anne-Cath
2cafa78339 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-27 18:22:22 +01:00
Eric Espie
f3f86017b6 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-27 18:14:28 +01:00
Eric Espie
5479080eb2 Merge remote-tracking branch 'origin/support/3.1' into develop 2024-02-27 17:40:56 +01:00
Benjamin Dalsass
3cb3e8a7f9 N°6937 - Symfony 6.4 - Handle Symfony configuration files 2024-02-26 10:38:36 +01:00
Molkobain
6a907f1fed Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-22 16:08:09 +01:00
Benjamin Dalsass
241f845c08 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-21 10:50:44 +01:00
Benjamin Dalsass
623f63abb3 N°7279 - AttributeClass defined in XML datamodel compilation issue 2024-02-21 09:53:57 +01:00
Pierre Goiffon
293adc3a99 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-20 12:12:51 +01:00
Pierre Goiffon
dee9f90a0b Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-20 09:27:51 +01:00
Pierre Goiffon
a7348f0eb9 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-20 09:13:10 +01:00
Molkobain
7457735c04 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-19 20:24:26 +01:00
Molkobain
0f389b2a48 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-19 10:00:21 +01:00
Stephen Abello
bfe01899a4 N°7243 - Add toast notifications to iTop (#614)
* N°7243 - Add toast notifications to iTop

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Update js/pages/backoffice/toolbox.js

* Update js/utils.js

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

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2024-02-16 10:59:05 +01:00
Pierre Goiffon
9531762c44 N°7252 Remove unused files in /js 2024-02-15 17:23:02 +01:00
Pierre Goiffon
e59a35e804 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-15 17:20:55 +01:00
Pierre Goiffon
21f5f5fe5e Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-15 14:53:43 +01:00
Pierre Goiffon
e6483fed98 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-15 11:11:59 +01:00
Pierre Goiffon
98bc04697e Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-15 09:51:46 +01:00
Pierre Goiffon
38e9b59b89 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-14 15:17:48 +01:00
Pierre Goiffon
118b22fe56 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-14 15:13:54 +01:00
Pierre Goiffon
8062694331 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-09 13:41:47 +01:00
Pierre Goiffon
e576235307 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-09 12:05:24 +01:00
Pierre Goiffon
e87502e7bf Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-08 11:35:03 +01:00
Molkobain
400ed9e999 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-07 15:05:19 +01:00
Molkobain
5b01ad23c4 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-06 21:53:38 +01:00
Pierre Goiffon
9a06fa4704 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-01 16:12:34 +01:00
Pierre Goiffon
c5555ad365 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-02-01 10:30:17 +01:00
Pierre Goiffon
9c6db1d730 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-30 11:47:04 +01:00
Molkobain
30cfe69e26 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-30 09:00:45 +01:00
Pierre Goiffon
e45049a602 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-29 17:20:46 +01:00
Pierre Goiffon
82129ff3bd Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-29 16:31:52 +01:00
Timothee
593b603295 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-29 15:43:33 +01:00
Molkobain
54b2e41afd Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-29 15:07:10 +01:00
Molkobain
ede6e6dd87 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-24 15:22:21 +01:00
Molkobain
e18ea88735 N°6648 - Use \utils::GetDataPath() instead of hard-coded paths (#555)
* N°6648 - Use \utils::GetDataPath() instead of hard-coded paths

* Update setup/applicationinstaller.class.inc.php

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

---------

Co-authored-by: Thomas Casteleyn <thomas.casteleyn@super-visions.com>
2024-01-22 21:06:08 +01:00
Pierre Goiffon
750dfe746e Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-22 16:19:59 +01:00
Molkobain
53404f1002 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-17 23:06:16 +01:00
jf-cbd
5623784c59 N°7134 - Can't retrieve the list of changes when editing URP_UserProfile 2024-01-17 15:15:11 +01:00
Molkobain
d122de04e4 Merge remote-tracking branch 'origin/support/3.2' into develop 2024-01-16 19:57:16 +01:00
Pierre Goiffon
2fa9774955 📝 Version history: add 2.7.10 and 3.0.4 2024-01-16 18:22:44 +01:00
1774 changed files with 159788 additions and 124435 deletions

View File

@@ -79,6 +79,8 @@ Then, **for a method** of an eligible class:
## Installation ## Installation
Note : PHP7 is required. Migrating to PHP8 requires some additional work which is questionable as an alternative way to generate a documentation is being considered.
``` ```
cd .doc cd .doc
composer require phpdocumentor/phpdocumentor:~2 --dev composer require phpdocumentor/phpdocumentor:~2 --dev

View File

@@ -93,6 +93,12 @@ gitGraph
checkout support/3.2 checkout support/3.2
commit id: "2024-06-25" tag: "3.2.0-beta1" type: REVERSE commit id: "2024-06-25" tag: "3.2.0-beta1" type: REVERSE
commit id: "2024-08-07" tag: "3.2.0" commit id: "2024-08-07" tag: "3.2.0"
checkout support/2.7
commit id: "2025-02-25" tag: "2.7.12"
checkout support/3.1
commit id: "2025-02-25 " tag: "3.1.3"
checkout support/3.2
commit id: "2025-02-25 " tag: "3.2.1"
``` ```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start). To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

View File

@@ -31,7 +31,7 @@ jobs:
run: | run: |
curl -X POST -H "Authorization: token ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \ curl -X POST -H "Authorization: token ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \
-H "Accept: application/vnd.github.v3+json" \ -H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/Combodo/combodo-wikit-integration/issues/${{ github.event.pull_request.number }}/labels \ https://api.github.com/repos/Combodo/iTop/issues/${{ github.event.pull_request.number }}/labels \
-d '{"labels":["internal"]}' -d '{"labels":["internal"]}'
env: env:
is_member: ${{ env.is_member }} is_member: ${{ env.is_member }}

View File

@@ -25,12 +25,34 @@
if (count($argv) === 1) { if (count($argv) === 1) {
echo '⚠ You must pass the base tag/sha1 as parameter'; echo "⚠ You must pass the base tag/sha1 as parameter\n";
exit(1); exit(1);
} }
$sBaseReference = $argv[1]; $sBaseReference = $argv[1];
/**
* Replace the Github emojis codes by their UTF-8 character equivalent
*/
function ReplaceGitmojis(string $sLine)
{
static $aGitmojis = null;
if ($aGitmojis === null) {
$aRawGitmojis = json_decode(trim(file_get_contents(__DIR__.'/gitmojis.json')), true);
if ($aRawGitmojis === false) {
echo "\nFailed to parse ".__DIR__."/gitmojis.json, emoji codes will not be replaced by their unicode equivalent.\n";
} else {
foreach($aRawGitmojis["gitmojis"] as $aGitmoji) {
$aGitmojis[$aGitmoji['code']] = $aGitmoji['emoji'];
}
}
}
if (is_array($aGitmojis)) {
return str_replace(array_keys($aGitmojis), array_values($aGitmojis), $sLine);
}
}
//--- Get log //--- Get log
$sGitLogCommand = 'git log --decorate --pretty="%h;%s" --date-order --no-merges '.$sBaseReference.'..HEAD'; $sGitLogCommand = 'git log --decorate --pretty="%h;%s" --date-order --no-merges '.$sBaseReference.'..HEAD';
$sGitLogRaw = shell_exec($sGitLogCommand); $sGitLogRaw = shell_exec($sGitLogCommand);
@@ -73,5 +95,5 @@ echo "\n";
echo "# Logs line without bug referenced\n"; echo "# Logs line without bug referenced\n";
echo "sha1;subject\n"; echo "sha1;subject\n";
foreach ($aLogLineNoBug as $sLogLine) { foreach ($aLogLineNoBug as $sLogLine) {
echo "$sLogLine\n"; echo ReplaceGitmojis($sLogLine)."\n";
} }

589
.make/release/gitmojis.json Normal file
View File

@@ -0,0 +1,589 @@
{
"$schema": "https://gitmoji.dev/api/gitmojis/schema",
"gitmojis": [
{
"emoji": "🎨",
"entity": "&#x1f3a8;",
"code": ":art:",
"description": "Improve structure / format of the code.",
"name": "art",
"semver": null
},
{
"emoji": "⚡️",
"entity": "&#x26a1;",
"code": ":zap:",
"description": "Improve performance.",
"name": "zap",
"semver": "patch"
},
{
"emoji": "🔥",
"entity": "&#x1f525;",
"code": ":fire:",
"description": "Remove code or files.",
"name": "fire",
"semver": null
},
{
"emoji": "🐛",
"entity": "&#x1f41b;",
"code": ":bug:",
"description": "Fix a bug.",
"name": "bug",
"semver": "patch"
},
{
"emoji": "🚑️",
"entity": "&#128657;",
"code": ":ambulance:",
"description": "Critical hotfix.",
"name": "ambulance",
"semver": "patch"
},
{
"emoji": "✨",
"entity": "&#x2728;",
"code": ":sparkles:",
"description": "Introduce new features.",
"name": "sparkles",
"semver": "minor"
},
{
"emoji": "📝",
"entity": "&#x1f4dd;",
"code": ":memo:",
"description": "Add or update documentation.",
"name": "memo",
"semver": null
},
{
"emoji": "🚀",
"entity": "&#x1f680;",
"code": ":rocket:",
"description": "Deploy stuff.",
"name": "rocket",
"semver": null
},
{
"emoji": "💄",
"entity": "&#ff99cc;",
"code": ":lipstick:",
"description": "Add or update the UI and style files.",
"name": "lipstick",
"semver": "patch"
},
{
"emoji": "🎉",
"entity": "&#127881;",
"code": ":tada:",
"description": "Begin a project.",
"name": "tada",
"semver": null
},
{
"emoji": "✅",
"entity": "&#x2705;",
"code": ":white_check_mark:",
"description": "Add, update, or pass tests.",
"name": "white-check-mark",
"semver": null
},
{
"emoji": "🔒️",
"entity": "&#x1f512;",
"code": ":lock:",
"description": "Fix security or privacy issues.",
"name": "lock",
"semver": "patch"
},
{
"emoji": "🔐",
"entity": "&#x1f510;",
"code": ":closed_lock_with_key:",
"description": "Add or update secrets.",
"name": "closed-lock-with-key",
"semver": null
},
{
"emoji": "🔖",
"entity": "&#x1f516;",
"code": ":bookmark:",
"description": "Release / Version tags.",
"name": "bookmark",
"semver": null
},
{
"emoji": "🚨",
"entity": "&#x1f6a8;",
"code": ":rotating_light:",
"description": "Fix compiler / linter warnings.",
"name": "rotating-light",
"semver": null
},
{
"emoji": "🚧",
"entity": "&#x1f6a7;",
"code": ":construction:",
"description": "Work in progress.",
"name": "construction",
"semver": null
},
{
"emoji": "💚",
"entity": "&#x1f49a;",
"code": ":green_heart:",
"description": "Fix CI Build.",
"name": "green-heart",
"semver": null
},
{
"emoji": "⬇️",
"entity": "⬇️",
"code": ":arrow_down:",
"description": "Downgrade dependencies.",
"name": "arrow-down",
"semver": "patch"
},
{
"emoji": "⬆️",
"entity": "⬆️",
"code": ":arrow_up:",
"description": "Upgrade dependencies.",
"name": "arrow-up",
"semver": "patch"
},
{
"emoji": "📌",
"entity": "&#x1F4CC;",
"code": ":pushpin:",
"description": "Pin dependencies to specific versions.",
"name": "pushpin",
"semver": "patch"
},
{
"emoji": "👷",
"entity": "&#x1f477;",
"code": ":construction_worker:",
"description": "Add or update CI build system.",
"name": "construction-worker",
"semver": null
},
{
"emoji": "📈",
"entity": "&#x1F4C8;",
"code": ":chart_with_upwards_trend:",
"description": "Add or update analytics or track code.",
"name": "chart-with-upwards-trend",
"semver": "patch"
},
{
"emoji": "♻️",
"entity": "&#x267b;",
"code": ":recycle:",
"description": "Refactor code.",
"name": "recycle",
"semver": null
},
{
"emoji": "",
"entity": "&#10133;",
"code": ":heavy_plus_sign:",
"description": "Add a dependency.",
"name": "heavy-plus-sign",
"semver": "patch"
},
{
"emoji": "",
"entity": "&#10134;",
"code": ":heavy_minus_sign:",
"description": "Remove a dependency.",
"name": "heavy-minus-sign",
"semver": "patch"
},
{
"emoji": "🔧",
"entity": "&#x1f527;",
"code": ":wrench:",
"description": "Add or update configuration files.",
"name": "wrench",
"semver": "patch"
},
{
"emoji": "🔨",
"entity": "&#128296;",
"code": ":hammer:",
"description": "Add or update development scripts.",
"name": "hammer",
"semver": null
},
{
"emoji": "🌐",
"entity": "&#127760;",
"code": ":globe_with_meridians:",
"description": "Internationalization and localization.",
"name": "globe-with-meridians",
"semver": "patch"
},
{
"emoji": "✏️",
"entity": "&#59161;",
"code": ":pencil2:",
"description": "Fix typos.",
"name": "pencil2",
"semver": "patch"
},
{
"emoji": "💩",
"entity": "&#58613;",
"code": ":poop:",
"description": "Write bad code that needs to be improved.",
"name": "poop",
"semver": null
},
{
"emoji": "⏪️",
"entity": "&#9194;",
"code": ":rewind:",
"description": "Revert changes.",
"name": "rewind",
"semver": "patch"
},
{
"emoji": "🔀",
"entity": "&#128256;",
"code": ":twisted_rightwards_arrows:",
"description": "Merge branches.",
"name": "twisted-rightwards-arrows",
"semver": null
},
{
"emoji": "📦️",
"entity": "&#1F4E6;",
"code": ":package:",
"description": "Add or update compiled files or packages.",
"name": "package",
"semver": "patch"
},
{
"emoji": "👽️",
"entity": "&#1F47D;",
"code": ":alien:",
"description": "Update code due to external API changes.",
"name": "alien",
"semver": "patch"
},
{
"emoji": "🚚",
"entity": "&#1F69A;",
"code": ":truck:",
"description": "Move or rename resources (e.g.: files, paths, routes).",
"name": "truck",
"semver": null
},
{
"emoji": "📄",
"entity": "&#1F4C4;",
"code": ":page_facing_up:",
"description": "Add or update license.",
"name": "page-facing-up",
"semver": null
},
{
"emoji": "💥",
"entity": "&#x1f4a5;",
"code": ":boom:",
"description": "Introduce breaking changes.",
"name": "boom",
"semver": "major"
},
{
"emoji": "🍱",
"entity": "&#1F371",
"code": ":bento:",
"description": "Add or update assets.",
"name": "bento",
"semver": "patch"
},
{
"emoji": "♿️",
"entity": "&#9855;",
"code": ":wheelchair:",
"description": "Improve accessibility.",
"name": "wheelchair",
"semver": "patch"
},
{
"emoji": "💡",
"entity": "&#128161;",
"code": ":bulb:",
"description": "Add or update comments in source code.",
"name": "bulb",
"semver": null
},
{
"emoji": "🍻",
"entity": "&#x1f37b;",
"code": ":beers:",
"description": "Write code drunkenly.",
"name": "beers",
"semver": null
},
{
"emoji": "💬",
"entity": "&#128172;",
"code": ":speech_balloon:",
"description": "Add or update text and literals.",
"name": "speech-balloon",
"semver": "patch"
},
{
"emoji": "🗃️",
"entity": "&#128451;",
"code": ":card_file_box:",
"description": "Perform database related changes.",
"name": "card-file-box",
"semver": "patch"
},
{
"emoji": "🔊",
"entity": "&#128266;",
"code": ":loud_sound:",
"description": "Add or update logs.",
"name": "loud-sound",
"semver": null
},
{
"emoji": "🔇",
"entity": "&#128263;",
"code": ":mute:",
"description": "Remove logs.",
"name": "mute",
"semver": null
},
{
"emoji": "👥",
"entity": "&#128101;",
"code": ":busts_in_silhouette:",
"description": "Add or update contributor(s).",
"name": "busts-in-silhouette",
"semver": null
},
{
"emoji": "🚸",
"entity": "&#128696;",
"code": ":children_crossing:",
"description": "Improve user experience / usability.",
"name": "children-crossing",
"semver": "patch"
},
{
"emoji": "🏗️",
"entity": "&#1f3d7;",
"code": ":building_construction:",
"description": "Make architectural changes.",
"name": "building-construction",
"semver": null
},
{
"emoji": "📱",
"entity": "&#128241;",
"code": ":iphone:",
"description": "Work on responsive design.",
"name": "iphone",
"semver": "patch"
},
{
"emoji": "🤡",
"entity": "&#129313;",
"code": ":clown_face:",
"description": "Mock things.",
"name": "clown-face",
"semver": null
},
{
"emoji": "🥚",
"entity": "&#129370;",
"code": ":egg:",
"description": "Add or update an easter egg.",
"name": "egg",
"semver": "patch"
},
{
"emoji": "🙈",
"entity": "&#8bdfe7;",
"code": ":see_no_evil:",
"description": "Add or update a .gitignore file.",
"name": "see-no-evil",
"semver": null
},
{
"emoji": "📸",
"entity": "&#128248;",
"code": ":camera_flash:",
"description": "Add or update snapshots.",
"name": "camera-flash",
"semver": null
},
{
"emoji": "⚗️",
"entity": "&#x2697;",
"code": ":alembic:",
"description": "Perform experiments.",
"name": "alembic",
"semver": "patch"
},
{
"emoji": "🔍️",
"entity": "&#128269;",
"code": ":mag:",
"description": "Improve SEO.",
"name": "mag",
"semver": "patch"
},
{
"emoji": "🏷️",
"entity": "&#127991;",
"code": ":label:",
"description": "Add or update types.",
"name": "label",
"semver": "patch"
},
{
"emoji": "🌱",
"entity": "&#127793;",
"code": ":seedling:",
"description": "Add or update seed files.",
"name": "seedling",
"semver": null
},
{
"emoji": "🚩",
"entity": "&#x1F6A9;",
"code": ":triangular_flag_on_post:",
"description": "Add, update, or remove feature flags.",
"name": "triangular-flag-on-post",
"semver": "patch"
},
{
"emoji": "🥅",
"entity": "&#x1F945;",
"code": ":goal_net:",
"description": "Catch errors.",
"name": "goal-net",
"semver": "patch"
},
{
"emoji": "💫",
"entity": "&#x1f4ab;",
"code": ":dizzy:",
"description": "Add or update animations and transitions.",
"name": "dizzy",
"semver": "patch"
},
{
"emoji": "🗑️",
"entity": "&#x1F5D1;",
"code": ":wastebasket:",
"description": "Deprecate code that needs to be cleaned up.",
"name": "wastebasket",
"semver": "patch"
},
{
"emoji": "🛂",
"entity": "&#x1F6C2;",
"code": ":passport_control:",
"description": "Work on code related to authorization, roles and permissions.",
"name": "passport-control",
"semver": "patch"
},
{
"emoji": "🩹",
"entity": "&#x1FA79;",
"code": ":adhesive_bandage:",
"description": "Simple fix for a non-critical issue.",
"name": "adhesive-bandage",
"semver": "patch"
},
{
"emoji": "🧐",
"entity": "&#x1F9D0;",
"code": ":monocle_face:",
"description": "Data exploration/inspection.",
"name": "monocle-face",
"semver": null
},
{
"emoji": "⚰️",
"entity": "&#x26B0;",
"code": ":coffin:",
"description": "Remove dead code.",
"name": "coffin",
"semver": null
},
{
"emoji": "🧪",
"entity": "&#x1F9EA;",
"code": ":test_tube:",
"description": "Add a failing test.",
"name": "test-tube",
"semver": null
},
{
"emoji": "👔",
"entity": "&#128084;",
"code": ":necktie:",
"description": "Add or update business logic.",
"name": "necktie",
"semver": "patch"
},
{
"emoji": "🩺",
"entity": "&#x1FA7A;",
"code": ":stethoscope:",
"description": "Add or update healthcheck.",
"name": "stethoscope",
"semver": null
},
{
"emoji": "🧱",
"entity": "&#x1f9f1;",
"code": ":bricks:",
"description": "Infrastructure related changes.",
"name": "bricks",
"semver": null
},
{
"emoji": "🧑‍💻",
"entity": "&#129489;&#8205;&#128187;",
"code": ":technologist:",
"description": "Improve developer experience.",
"name": "technologist",
"semver": null
},
{
"emoji": "💸",
"entity": "&#x1F4B8;",
"code": ":money_with_wings:",
"description": "Add sponsorships or money related infrastructure.",
"name": "money-with-wings",
"semver": null
},
{
"emoji": "🧵",
"entity": "&#x1F9F5;",
"code": ":thread:",
"description": "Add or update code related to multithreading or concurrency.",
"name": "thread",
"semver": null
},
{
"emoji": "🦺",
"entity": "&#x1F9BA;",
"code": ":safety_vest:",
"description": "Add or update code related to validation.",
"name": "safety-vest",
"semver": null
}
]
}

View File

@@ -90,6 +90,7 @@ We would like to give a special thank you 🤗 to the people from the community
- Dejin, Bie (a.k.a [@bdejin](https://github.com/bdejin)) - Dejin, Bie (a.k.a [@bdejin](https://github.com/bdejin))
- Dvořák, Lukáš - Dvořák, Lukáš
- Goethals, Stefan - Goethals, Stefan
- Giuva, Vincenzo Katriel (a.k.a [@DarkNight97boss](https://github.com/DarkNight97boss))
- Gumble, David - Gumble, David
- Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb)) - Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb))
- Kaltefleiter, Lars (a.k.a [@larhip](https://www.github.com/larhip)) - Kaltefleiter, Lars (a.k.a [@larhip](https://www.github.com/larhip))
@@ -106,6 +107,7 @@ We would like to give a special thank you 🤗 to the people from the community
- Raenker, Martin - Raenker, Martin
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard)) - Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
- Rosenke, Stephan - Rosenke, Stephan
- Rossi, Tommaso (a.k.a [@tomrss](https://www.github.com/tomrss))
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern)) - Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge) - Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
- Seki, Shoji - Seki, Shoji
@@ -115,6 +117,7 @@ We would like to give a special thank you 🤗 to the people from the community
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby)) - Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
- Tulio, Marco - Tulio, Marco
- Turrubiates, Miguel - Turrubiates, Miguel
- Vlk, Karel (a.k.a [@vlk-charles](https://www.github.com/vlk-charles))
### Aliases ### Aliases

View File

@@ -825,49 +825,38 @@ class UserRightsProfile extends UserRightsAddOnAPI
{ {
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading // We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
// We have to answer NO for objects shared for reading purposes // We have to answer NO for objects shared for reading purposes
if (self::HasSharing()) if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
{ // This class is shared, GetSelectFilter may allow some objects for read only
$aClassProps = SharedObject::GetSharedClassProperties($sClass); // But currently we are checking whether the objects might be written...
if ($aClassProps) // Let's exclude the objects based on the relevant criteria
{
// This class is shared, GetSelectFilter may allow some objects for read only
// But currently we are checking wether the objects might be written...
// Let's exclude the objects based on the relevant criteria
$sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass); // Use $oInstanceSet only if sClass is the main class
if (!is_null($sOrgAttCode)) if (!is_a($oInstanceSet->GetClass(), $sClass, true)) {
{ /** @var \DBObjectSet $oInstanceSet */
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass); throw new CoreException(__FUNCTION__.': Expecting object set to be of class '.$sClass.' but it is of class '.$oInstanceSet->GetClass(), ['OQL_Query' => $oInstanceSet->GetFilter()->ToOQL(), 'classes' => $oInstanceSet->GetSelectedClasses()]);
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) }
{ $sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass);
$iCountNO = 0; if (!is_null($sOrgAttCode)) {
$iCountYES = 0; $aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
$oInstanceSet->Rewind(); if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) {
while($oObject = $oInstanceSet->Fetch()) $iCountNO = 0;
{ $iCountYES = 0;
$iOrg = $oObject->Get($sOrgAttCode); $oInstanceSet->Rewind();
if (in_array($iOrg, $aUserOrgs)) while ($oObject = $oInstanceSet->Fetch()) {
{ $iOrg = $oObject->Get($sOrgAttCode);
$iCountYES++; if (in_array($iOrg, $aUserOrgs)) {
} $iCountYES++;
else } else {
{ $iCountNO++;
$iCountNO++;
}
}
if ($iCountNO == 0)
{
$iPermission = UR_ALLOWED_YES;
}
elseif ($iCountYES == 0)
{
$iPermission = UR_ALLOWED_NO;
}
else
{
$iPermission = UR_ALLOWED_DEPENDS;
} }
} }
if ($iCountNO == 0) {
$iPermission = UR_ALLOWED_YES;
} elseif ($iCountYES == 0) {
$iPermission = UR_ALLOWED_NO;
} else {
$iPermission = UR_ALLOWED_DEPENDS;
}
} }
} }
} }
@@ -982,4 +971,3 @@ class UserRightsProfile extends UserRightsAddOnAPI
UserRights::SelectModule('UserRightsProfile'); UserRights::SelectModule('UserRightsProfile');
?>

View File

@@ -399,25 +399,25 @@ class URP_ActionGrant extends UserRightsBaseClass
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "profileid", "name_attcode" => "profileid",
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"db_table" => "priv_urp_grant_actions", "db_table" => "priv_urp_grant_actions",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes(); //MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked) // Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_SILENT, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_SILENT, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name"))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'action')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'action')); // Attributes to be displayed for the complete details
@@ -435,25 +435,25 @@ class URP_StimulusGrant extends UserRightsBaseClass
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "profileid", "name_attcode" => "profileid",
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"db_table" => "priv_urp_grant_stimulus", "db_table" => "priv_urp_grant_stimulus",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes(); //MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked) // Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_SILENT, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_SILENT, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name"))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'stimulus')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'stimulus')); // Attributes to be displayed for the complete details

View File

@@ -402,7 +402,7 @@ class URP_ClassProjection extends UserRightsBaseClass
MetaModel::Init_AddAttribute(new AttributeExternalKey("dimensionid", array("targetclass"=>"URP_Dimensions", "jointype"=> "", "allowed_values"=>null, "sql"=>"dimensionid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("dimensionid", array("targetclass"=>"URP_Dimensions", "jointype"=> "", "allowed_values"=>null, "sql"=>"dimensionid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("dimension", array("allowed_values"=>null, "extkey_attcode"=> 'dimensionid', "target_attcode"=>"name"))); MetaModel::Init_AddAttribute(new AttributeExternalField("dimension", array("allowed_values"=>null, "extkey_attcode"=> 'dimensionid', "target_attcode"=>"name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("attribute", array("allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("attribute", array("allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
@@ -459,25 +459,25 @@ class URP_ActionGrant extends UserRightsBaseClass
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "profileid", "name_attcode" => "profileid",
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"db_table" => "priv_urp_grant_actions", "db_table" => "priv_urp_grant_actions",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes(); //MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked) // Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name"))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'action')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'action')); // Attributes to be displayed for the complete details
@@ -495,25 +495,25 @@ class URP_StimulusGrant extends UserRightsBaseClass
{ {
$aParams = array $aParams = array
( (
"category" => "addon/userrights", "category" => "addon/userrights",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "profileid", "name_attcode" => "profileid",
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"db_table" => "priv_urp_grant_stimulus", "db_table" => "priv_urp_grant_stimulus",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes(); //MetaModel::Init_InheritAttributes();
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked) // Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name"))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category"=>"", "more_values"=>"", "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeClass("class", array("class_category" => "", "more_values" => "", "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'stimulus')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('profileid', 'class', 'permission', 'stimulus')); // Attributes to be displayed for the complete details

View File

@@ -1711,6 +1711,16 @@ interface iRestServiceProvider
public function ExecOperation($sVersion, $sVerb, $aParams); public function ExecOperation($sVersion, $sVerb, $aParams);
} }
/**
* A REST service provider implementing this interface will have its input JSON data sanitized for logging purposes
* @since 2.7.13, 3.2.1-1
* @see \iRestServiceProvider
*/
interface iRestInputSanitizer
{
public function SanitizeJsonInput(string $sJsonInput): string;
}
/** /**
* Minimal REST response structure. Derive this structure to add response data and error codes. * Minimal REST response structure. Derive this structure to add response data and error codes.
* *
@@ -1802,6 +1812,14 @@ class RestResult
* @api * @api
*/ */
public $message; public $message;
/**
* Sanitize the content of this result to hide sensitive information
*/
public function SanitizeContent()
{
// The default implementation does nothing
}
} }
/** /**

View File

@@ -698,10 +698,10 @@ HTML
$sLinkedClass = $oAttDef->GetLinkedClass(); $sLinkedClass = $oAttDef->GetLinkedClass();
// Filter out links pointing to obsolete objects (if relevant) // Filter out links pointing to obsolete objects (if relevant)
$oOrmLinkSet = $this->Get($sAttCode); $oOrmLinkSet = $this->Get($sAttCode);
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData()); $oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData());
$iCount = $oLinkSet->Count();
$iCount = $oLinkSet->Count();
if ($this->IsNew()) { if ($this->IsNew()) {
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode); $iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
} else { } else {
@@ -766,9 +766,9 @@ HTML
$oPage->add($sHTMLValue); $oPage->add($sHTMLValue);
} else { } else {
if ($oAttDef->IsIndirect()) { if ($oAttDef->IsIndirect()) {
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly); $oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly, $iCount);
} else { } else {
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly); $oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly, $iCount);
} }
$oPage->AddUiBlock($oBlockLinkSetViewTable); $oPage->AddUiBlock($oBlockLinkSetViewTable);
} }
@@ -805,16 +805,16 @@ HTML
if (!$this->IsNew()) { if (!$this->IsNew()) {
// Look for any trigger that considers this object as "In Scope" // Look for any trigger that considers this object as "In Scope"
// If any trigger has been found then display a tab with notifications // If any trigger has been found then display a tab with notifications
// // If all triggers on an object have been deleted, we consider that we no longer need the event notification information
$aTriggers = $this->GetRelatedTriggersIDs(); $aTriggers = $this->GetRelatedTriggersIDs();
if (count($aTriggers) > 0) { if (count($aTriggers) > 0) {
$iId = $this->GetKey(); $iId = $this->GetKey();
$aParams = array('triggers' => $aTriggers, 'id' => $iId); $aParams = array('class' => get_class($this), 'id' => $iId);
$aNotifSearches = array(); $aNotifSearches = array();
$iNotifsCount = 0; $iNotifsCount = 0;
$aNotificationClasses = MetaModel::EnumChildClasses('EventNotification'); $aNotificationClasses = MetaModel::EnumChildClasses('EventNotification');
foreach ($aNotificationClasses as $sNotifClass) { foreach ($aNotificationClasses as $sNotifClass) {
$aNotifSearches[$sNotifClass] = DBObjectSearch::FromOQL("SELECT $sNotifClass AS Ev JOIN Trigger AS T ON Ev.trigger_id = T.id WHERE T.id IN (:triggers) AND Ev.object_id = :id"); $aNotifSearches[$sNotifClass] = DBObjectSearch::FromOQL("SELECT $sNotifClass AS Ev WHERE Ev.object_id = :id AND Ev.object_class = :class");
$aNotifSearches[$sNotifClass]->SetInternalParams($aParams); $aNotifSearches[$sNotifClass]->SetInternalParams($aParams);
$oNotifSet = new DBObjectSet($aNotifSearches[$sNotifClass], array()); $oNotifSet = new DBObjectSet($aNotifSearches[$sNotifClass], array());
$iNotifsCount += $oNotifSet->Count(); $iNotifsCount += $oNotifSet->Count();
@@ -1113,8 +1113,10 @@ HTML
} }
// Note: DisplayBareHeader is called before adding $oObjectDetails to the page, so it can inject HTML before it through $oPage. // Note: DisplayBareHeader is called before adding $oObjectDetails to the page, so it can inject HTML before it through $oPage.
/** @var iTopWebPage $oPage */ /** @var \iTopWebPage $oPage */
$oKPI = new ExecutionKPI();
$aHeadersBlocks = $this->DisplayBareHeader($oPage, $bEditMode); $aHeadersBlocks = $this->DisplayBareHeader($oPage, $bEditMode);
$oKPI->ComputeStatsForExtension($this, 'DisplayBareHeader');
if (false === empty($aHeadersBlocks['subtitle'])) { if (false === empty($aHeadersBlocks['subtitle'])) {
$oObjectDetails->AddSubTitleBlocks($aHeadersBlocks['subtitle']); $oObjectDetails->AddSubTitleBlocks($aHeadersBlocks['subtitle']);
} }
@@ -1127,8 +1129,12 @@ HTML
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, '', $oObjectDetails); $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, '', $oObjectDetails);
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB); $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTab('UI:PropertiesTab'); $oPage->SetCurrentTab('UI:PropertiesTab');
$oKPI = new ExecutionKPI();
$this->DisplayBareProperties($oPage, $bEditMode); $this->DisplayBareProperties($oPage, $bEditMode);
$oKPI->ComputeStatsForExtension($this, 'DisplayBareProperties');
$oKPI = new ExecutionKPI();
$this->DisplayBareRelations($oPage, $bEditMode); $this->DisplayBareRelations($oPage, $bEditMode);
$oKPI->ComputeStatsForExtension($this, 'DisplayBareRelations');
// Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle // Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle
@@ -3439,8 +3445,18 @@ EOF
} }
$sInputType = ''; $sInputType = '';
$sInputId = 'att_'.$iFieldIndex; $sInputId = 'att_'.$iFieldIndex;
$value = $this->Get($sAttCode);
$sDisplayValue = $this->GetEditValue($sAttCode);
if ($oAttDef instanceof AttributeDateTime && !$oAttDef->IsNullAllowed() && $value === $oAttDef->GetNullValue()) {
$value = $oAttDef->GetDefaultValue($this);
if ($value !== $oAttDef->GetNullValue()) {
// Set default date
$this->Set($sAttCode, $value);
$sDisplayValue = $this->GetEditValue($sAttCode);
}
}
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,
$this->Get($sAttCode), $this->GetEditValue($sAttCode), $sInputId, '', $iExpectCode, $value, $sDisplayValue, $sInputId, '', $iExpectCode,
$aArgs, true, $sInputType); $aArgs, true, $sInputType);
$aAttrib = array( $aAttrib = array(
'label' => '<span>'.$oAttDef->GetLabel().'</span>', 'label' => '<span>'.$oAttDef->GetLabel().'</span>',
@@ -5190,7 +5206,7 @@ HTML
$aKeys = array_keys($aValues[$sAttCode]); $aKeys = array_keys($aValues[$sAttCode]);
$currValue = $aKeys[0]; // The only value is the first key $currValue = $aKeys[0]; // The only value is the first key
if ($oAttDef->GetEditClass() == 'LinkedSet') { if ($oAttDef->GetEditClass() == 'LinkedSet') {
$oOrmLinkSet = $oDummyObj->Get($sAttCode); $oOrmLinkSet = $oDummyObj->Get($sAttCode);
LinkSetDataTransformer::StringToOrmLinkSet($aValues[$sAttCode][$currValue]['edit_value'], $oOrmLinkSet); LinkSetDataTransformer::StringToOrmLinkSet($aValues[$sAttCode][$currValue]['edit_value'], $oOrmLinkSet);
} else { } else {
@@ -5244,7 +5260,7 @@ HTML
} }
$oDummyObj->Set($sAttCode, $oTagSet); $oDummyObj->Set($sAttCode, $oTagSet);
} else if ($oAttDef->GetEditClass() == 'LinkedSet') { } else if ($oAttDef->GetEditClass() == 'LinkedSet') {
$oOrmLinkSet = $oDummyObj->Get($sAttCode); $oOrmLinkSet = $oDummyObj->Get($sAttCode);
foreach ($aMultiValues as $key => $sValue) { foreach ($aMultiValues as $key => $sValue) {
LinkSetDataTransformer::StringToOrmLinkSet($sValue['edit_value'], $oOrmLinkSet); LinkSetDataTransformer::StringToOrmLinkSet($sValue['edit_value'], $oOrmLinkSet);
} }
@@ -5923,14 +5939,14 @@ JS
* *
* @since 3.1.0 * @since 3.1.0
*/ */
final protected function FireEventCheckToWrite(): void final protected function FireEventCheckToWrite(?string $sStimulusBeingApplied): void
{ {
$this->FireEvent(EVENT_DB_CHECK_TO_WRITE, ['is_new' => $this->IsNew()]); $this->FireEvent(EVENT_DB_CHECK_TO_WRITE, ['is_new' => $this->IsNew(), 'stimulus_applied' => $sStimulusBeingApplied]);
} }
final protected function FireEventBeforeWrite() final protected function FireEventBeforeWrite(?string $sStimulusBeingApplied)
{ {
$this->FireEvent(EVENT_DB_BEFORE_WRITE, ['is_new' => $this->IsNew()]); $this->FireEvent(EVENT_DB_BEFORE_WRITE, ['is_new' => $this->IsNew(), 'stimulus_applied' => $sStimulusBeingApplied]);
} }
/** /**
@@ -5942,11 +5958,11 @@ JS
* @throws \CoreException * @throws \CoreException
* @since 3.1.0 * @since 3.1.0
*/ */
final protected function FireEventAfterWrite(array $aChanges, bool $bIsNew): void final protected function FireEventAfterWrite(array $aChanges, bool $bIsNew, ?string $sStimulusBeingApplied): void
{ {
$this->NotifyAttachedObjectsOnLinkClassModification(); $this->NotifyAttachedObjectsOnLinkClassModification();
$this->RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey()); $this->RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges]); $this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied]);
} }
////////////// //////////////
@@ -6087,7 +6103,9 @@ JS
// We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener // We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
// By disabling the event to be fired, we can remove the current object from the attribute ! // By disabling the event to be fired, we can remove the current object from the attribute !
$oObject = MetaModel::GetObject($sClass, $sId, false); $oObject = MetaModel::GetObject($sClass, $sId, false);
self::FireEventDbLinksChangedForObject($oObject); if (!is_null($oObject)) {
self::FireEventDbLinksChangedForObject($oObject);
}
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId); self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
} }
@@ -6095,13 +6113,11 @@ JS
{ {
self::SetEventDBLinksChangedBlocked(true); self::SetEventDBLinksChangedBlocked(true);
// N°6408 The object can have been deleted // N°6408 The object can have been deleted
if (!is_null($oObject)) { $oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
// Update the object if needed // Update the object if needed
if (count($oObject->ListChanges()) !== 0) { if (count($oObject->ListChanges()) !== 0) {
$oObject->DBUpdate(); $oObject->DBUpdate();
}
} }
cmdbAbstractObject::SetEventDBLinksChangedBlocked(false); cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);
} }
@@ -6179,9 +6195,9 @@ JS
* @inheritDoc * @inheritDoc
* @throws \CoreException * @throws \CoreException
*/ */
final protected function FireEventComputeValues(): void final protected function FireEventComputeValues(?string $sStimulusBeingApplied): void
{ {
$this->FireEvent(EVENT_DB_COMPUTE_VALUES); $this->FireEvent(EVENT_DB_COMPUTE_VALUES, ['is_new' => $this->IsNew(), 'stimulus_applied' => $sStimulusBeingApplied]);
} }
/** /**

View File

@@ -296,21 +296,21 @@ abstract class Dashboard
public function FromParams($aParams) public function FromParams($aParams)
{ {
$this->sLayoutClass = $aParams['layout_class']; $this->sLayoutClass = $aParams['layout_class'];
if (!is_subclass_of($this->sLayoutClass,DashboardLayout::class)) {
throw new InvalidParameterException('Invalid parameter layout_class "'.$aParams['layout_class'].'"');
}
$this->sTitle = $aParams['title']; $this->sTitle = $aParams['title'];
$this->bAutoReload = $aParams['auto_reload'] == 'true'; $this->bAutoReload = $aParams['auto_reload'] == 'true';
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']); $this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
foreach($aParams['cells'] as $aCell) foreach($aParams['cells'] as $aCell) {
{
$aCellDashlets = array(); $aCellDashlets = array();
foreach($aCell as $aDashletParams) foreach($aCell as $aDashletParams) {
{
$sDashletClass = $aDashletParams['dashlet_class']; $sDashletClass = $aDashletParams['dashlet_class'];
$sId = $aDashletParams['dashlet_id']; $sId = $aDashletParams['dashlet_id'];
/** @var \Dashlet $oNewDashlet */ /** @var \Dashlet $oNewDashlet */
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId); $oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
if (isset($aDashletParams['dashlet_type'])) if (isset($aDashletParams['dashlet_type'])) {
{
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']); $oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
} }
$oForm = $oNewDashlet->GetForm(); $oForm = $oNewDashlet->GetForm();
@@ -1266,13 +1266,12 @@ EOF
$sOkButtonLabel = Dict::S('UI:Button:Save'); $sOkButtonLabel = Dict::S('UI:Button:Save');
$sCancelButtonLabel = Dict::S('UI:Button:Cancel'); $sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$sId = utils::HtmlEntities($this->sId); $sId = json_encode($this->sId);
$sLayoutClass = utils::HtmlEntities($this->sLayoutClass); $sLayoutClass = json_encode($this->sLayoutClass);
$sAutoReload = $this->bAutoReload ? 'true' : 'false'; $sAutoReload = $this->bAutoReload ? 'true' : 'false';
$sAutoReloadSec = (string) $this->iAutoReloadSec; $sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = utils::HtmlEntities($this->sTitle); $sTitle = json_encode($this->sTitle);
$sFile = utils::HtmlEntities($this->GetDefinitionFile()); $sFile = json_encode($this->GetDefinitionFile());
$sFileForJS = json_encode($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php'; $sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = $this->GetReloadURL(); $sReloadURL = $this->GetReloadURL();
@@ -1328,15 +1327,15 @@ $('#dashboard_editor').dialog({
}); });
$('#dashboard_editor .ui-layout-center').runtimedashboard({ $('#dashboard_editor .ui-layout-center').runtimedashboard({
dashboard_id: '$sId', dashboard_id: $sId,
layout_class: '$sLayoutClass', layout_class: $sLayoutClass,
title: '$sTitle', title: $sTitle,
auto_reload: $sAutoReload, auto_reload: $sAutoReload,
auto_reload_sec: $sAutoReloadSec, auto_reload_sec: $sAutoReloadSec,
submit_to: '$sUrl', submit_to: '$sUrl',
submit_parameters: {operation: 'save_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'}, submit_parameters: {operation: 'save_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl', render_to: '$sUrl',
render_parameters: {operation: 'render_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'}, render_parameters: {operation: 'render_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
new_dashlet_parameters: {operation: 'new_dashlet'} new_dashlet_parameters: {operation: 'new_dashlet'}
}); });

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2"> <itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3">
<classes> <classes>
<class id="AbstractResource" _delta="define"> <class id="AbstractResource" _delta="define">
<parent>cmdbAbstractObject</parent> <parent>cmdbAbstractObject</parent>
@@ -45,7 +45,7 @@
<properties> <properties>
<comment>/** Acknowledge welcome popup messages */</comment> <comment>/** Acknowledge welcome popup messages */</comment>
<abstract>false</abstract> <abstract>false</abstract>
<category></category> <category/>
<key_type>autoincrement</key_type> <key_type>autoincrement</key_type>
<db_table>priv_welcome_popup_acknowledge</db_table> <db_table>priv_welcome_popup_acknowledge</db_table>
</properties> </properties>
@@ -238,6 +238,10 @@ The object can be modified.]]></description>
<description>Creation flag</description> <description>Creation flag</description>
<type>boolean</type> <type>boolean</type>
</event_datum> </event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>
@@ -263,6 +267,10 @@ Call $this->AddCheckWarning($sWarningMessage) to display a warning.
<description>Creation flag</description> <description>Creation flag</description>
<type>boolean</type> <type>boolean</type>
</event_datum> </event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>
@@ -290,6 +298,10 @@ The modifications can be propagated to other objects.]]></description>
<description><![CDATA[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> <type>array</type>
</event_datum> </event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>
@@ -420,6 +432,14 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
<description>The object inserted</description> <description>The object inserted</description>
<type>DBObject</type> <type>DBObject</type>
</event_datum> </event_datum>
<event_datum id="is_new">
<description>Creation flag</description>
<type>boolean</type>
</event_datum>
<event_datum id="stimulus_applied">
<description>Life cycle stimulus applied (null if not within a transition)</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info"> <event_datum id="debug_info">
<description>Debug string</description> <description>Debug string</description>
<type>string</type> <type>string</type>

View File

@@ -263,6 +263,8 @@ class DisplayBlock
/** param for export.php */ /** param for export.php */
'refresh_action', 'refresh_action',
/**to add refresh button in datatable*/ /**to add refresh button in datatable*/
'object_count',
/** int number of objects in list */
], DataTableUIBlockFactory::GetAllowedParams()), ], DataTableUIBlockFactory::GetAllowedParams()),
static::ENUM_STYLE_LIST_SEARCH => array_merge([ static::ENUM_STYLE_LIST_SEARCH => array_merge([
'update_history', 'update_history',
@@ -1860,7 +1862,11 @@ class MenuBlock extends DisplayBlock
$aSelectedClasses = $this->GetFilter()->GetSelectedClasses(); $aSelectedClasses = $this->GetFilter()->GetSelectedClasses();
$bIsForLinkset = isset($aExtraParams['target_attr']); $bIsForLinkset = isset($aExtraParams['target_attr']);
$oSet = new CMDBObjectSet($this->GetFilter()); $oSet = new CMDBObjectSet($this->GetFilter());
$iSetCount = $oSet->Count(); if(isset($aExtraParams['object_count'])){
$iSetCount = $aExtraParams['object_count'];
} else {
$iSetCount = $oSet->Count();
}
/** @var string $sRefreshAction JS snippet to run when clicking on the refresh button of the menu */ /** @var string $sRefreshAction JS snippet to run when clicking on the refresh button of the menu */
$sRefreshAction = $aExtraParams['refresh_action'] ?? ''; $sRefreshAction = $aExtraParams['refresh_action'] ?? '';
$bIsCreationInModal = isset($aExtraParams['creation_in_modal']) && $aExtraParams['creation_in_modal'] === true; $bIsCreationInModal = isset($aExtraParams['creation_in_modal']) && $aExtraParams['creation_in_modal'] === true;
@@ -2024,8 +2030,8 @@ class MenuBlock extends DisplayBlock
$sSelectedClassName = MetaModel::GetName($sSelectedClass); $sSelectedClassName = MetaModel::GetName($sSelectedClass);
// Check rights on class // Check rights on class
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); $bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE, $sSelectedClass); $bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE);
// Refine filter on selected class so bullk actions occur on the right class // Refine filter on selected class so bullk actions occur on the right class
$oSelectedClassFilter = $this->GetFilter()->DeepClone(); $oSelectedClassFilter = $this->GetFilter()->DeepClone();

View File

@@ -303,7 +303,7 @@ class ExcelExporter
{ {
if ($this->sOutputFilePath == null) if ($this->sOutputFilePath == null)
{ {
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx'; return utils::GetDataPath().'bulk_export/'.$this->sToken.'.xlsx';
} }
else else
{ {
@@ -313,14 +313,14 @@ class ExcelExporter
public static function GetExcelFileFromToken($sToken) public static function GetExcelFileFromToken($sToken)
{ {
return @file_get_contents(APPROOT.'data/bulk_export/'.$sToken.'.xlsx'); return @file_get_contents(utils::GetDataPath().'bulk_export/'.$sToken.'.xlsx');
} }
public static function CleanupFromToken($sToken) public static function CleanupFromToken($sToken)
{ {
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.status'); @unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.status');
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.data'); @unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.data');
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.xlsx'); @unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.xlsx');
} }
public function Cleanup() public function Cleanup()
@@ -334,7 +334,7 @@ class ExcelExporter
*/ */
public static function CleanupOldFiles() public static function CleanupOldFiles()
{ {
$aFiles = glob(APPROOT.'data/bulk_export/*.*'); $aFiles = glob(utils::GetDataPath().'bulk_export/*.*');
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay'); $iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
if($iDelay > 0) if($iDelay > 0)
@@ -416,14 +416,14 @@ class ExcelExporter
protected function CheckDataDir() protected function CheckDataDir()
{ {
if(!is_dir(APPROOT."data/bulk_export")) if(!is_dir(utils::GetDataPath()."bulk_export"))
{ {
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */); @mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
clearstatcache(); clearstatcache();
} }
if (!is_writable(APPROOT."data/bulk_export")) if (!is_writable(utils::GetDataPath()."bulk_export"))
{ {
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.'); throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
} }
} }
@@ -433,12 +433,12 @@ class ExcelExporter
{ {
$sToken = $this->sToken; $sToken = $this->sToken;
} }
return APPROOT."data/bulk_export/$sToken.status"; return utils::GetDataPath()."bulk_export/$sToken.status";
} }
protected function GetDataFile() protected function GetDataFile()
{ {
return APPROOT.'data/bulk_export/'.$this->sToken.'.data'; return utils::GetDataPath().'bulk_export/'.$this->sToken.'.data';
} }
protected function GetNewToken() protected function GetNewToken()

View File

@@ -36,29 +36,30 @@ class InputOutputTask extends cmdbAbstractObject
{ {
$aParams = array $aParams = array
( (
"category" => "application", "category" => "application",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "name", "name_attcode" => "name",
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array(), "reconc_keys" => array(),
"db_table" => "priv_iotask", "db_table" => "priv_iotask",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values"=>new ValueSetEnum('Input, Ouput'), "sql"=>"category", "default_value"=>"Input", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values" => new ValueSetEnum('Input, Ouput'), "sql" => "category", "default_value" => "Input", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values"=>new ValueSetEnum('File, Database, Web Service'), "sql"=>"source_type", "default_value"=>"File", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values" => new ValueSetEnum('File, Database, Web Service'), "sql" => "source_type", "default_value" => "File", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", array("allowed_values"=>new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql"=>"source_subtype", "default_value"=>"CSV", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype",
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values"=>null, "sql"=>"source_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); array("allowed_values" => new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql" => "source_subtype", "default_value" => "CSV", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category"=>"", "more_values"=>"", "sql"=>"objects_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values" => null, "sql" => "source_path", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"test_mode", "default_value"=>'No', "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category" => "", "more_values" => "", "sql" => "objects_class", "default_value" => null, "is_null_allowed" => true, "depends_on" => array(), "class_exclusion_list" => null)));
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"verbose_mode", "default_value" => 'No', "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "test_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values"=>new ValueSetEnum('Full, Update Only, Creation Only'), "sql"=>"options", "default_value"=> 'Full', "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "verbose_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values" => new ValueSetEnum('Full, Update Only, Creation Only'), "sql" => "options", "default_value" => 'Full', "is_null_allowed" => true, "depends_on" => array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path' , 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path', 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list MetaModel::Init_SetZListItems('list', array('description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
// Search criteria // Search criteria
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form

View File

@@ -1159,11 +1159,11 @@ class OQLMenuNode extends MenuNode
{ {
$sUsageId = utils::GetSafeId($sUsageId); $sUsageId = utils::GetSafeId($sUsageId);
$oSearch = DBObjectSearch::FromOQL($sOql); $oSearch = DBObjectSearch::FromOQL($sOql);
$sClass= $oSearch->GetClass(); $sClass= $oSearch->GetClass();
$sIcon = MetaModel::GetClassIcon($sClass, false); $sIcon = MetaModel::GetClassIcon($sClass, false);
if ($bSearchPane) { if ($bSearchPane) {
$aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams); $aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams);
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams); $oBlock = new DisplayBlock($oSearch, DisplayBlock::ENUM_STYLE_SEARCH, false /* Asynchronous */, $aParams);
$oBlock->Display($oPage, 0); $oBlock->Display($oPage, 0);
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>"); $oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
} }

View File

@@ -228,7 +228,7 @@ class privUITransactionFile
*/ */
public static function GetNewTransactionId() public static function GetNewTransactionId()
{ {
if (!is_dir(APPROOT.'data/transactions')) if (!is_dir(utils::GetDataPath().'transactions'))
{ {
if (!is_writable(APPROOT.'data')) if (!is_writable(APPROOT.'data'))
{ {
@@ -236,22 +236,22 @@ class privUITransactionFile
} }
// condition avoids race condition N°2345 // condition avoids race condition N°2345
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition // See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
if (!mkdir($concurrentDirectory = APPROOT.'data/transactions') && !is_dir($concurrentDirectory)) if (!mkdir($concurrentDirectory = utils::GetDataPath().'transactions') && !is_dir($concurrentDirectory))
{ {
throw new Exception('Failed to create the directory "'.APPROOT.'data/transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.'); throw new Exception('Failed to create the directory "'.utils::GetDataPath().'transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
} }
} }
if (!is_writable(APPROOT.'data/transactions')) if (!is_writable(utils::GetDataPath().'transactions'))
{ {
throw new Exception('The directory "'.APPROOT.'data/transactions" must be writable to the application.'); throw new Exception('The directory "'.utils::GetDataPath().'transactions" must be writable to the application.');
} }
$iCurrentUserId = static::GetCurrentUserId(); $iCurrentUserId = static::GetCurrentUserId();
self::CleanupOldTransactions(); self::CleanupOldTransactions();
$sTransactionIdFullPath = tempnam(APPROOT.'data/transactions', static::GetUserPrefix()); $sTransactionIdFullPath = tempnam(utils::GetDataPath().'transactions', static::GetUserPrefix());
file_put_contents($sTransactionIdFullPath, $iCurrentUserId, LOCK_EX); file_put_contents($sTransactionIdFullPath, $iCurrentUserId, LOCK_EX);
$sTransactionIdFileName = basename($sTransactionIdFullPath); $sTransactionIdFileName = basename($sTransactionIdFullPath);
@@ -274,8 +274,8 @@ class privUITransactionFile
*/ */
public static function IsTransactionValid($id, $bRemoveTransaction = true) public static function IsTransactionValid($id, $bRemoveTransaction = true)
{ {
// Constraint the transaction file within APPROOT.'data/transactions' // Constraint the transaction file within utils::GetDataPath().'transactions'
$sTransactionDir = realpath(APPROOT.'data/transactions'); $sTransactionDir = realpath(utils::GetDataPath().'transactions');
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir); $sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath))) if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
{ {
@@ -348,7 +348,7 @@ class privUITransactionFile
clearstatcache(); clearstatcache();
$iLimit = time() - 24*3600; $iLimit = time() - 24*3600;
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : APPROOT.'data/transactions/*'; $sPattern = $sTransactionDir ? "$sTransactionDir/*" : utils::GetDataPath().'transactions/*';
$aTransactions = glob($sPattern); $aTransactions = glob($sPattern);
foreach($aTransactions as $sFileName) foreach($aTransactions as $sFileName)
{ {
@@ -368,7 +368,7 @@ class privUITransactionFile
{ {
clearstatcache(); clearstatcache();
$aResult = array(); $aResult = array();
$aTransactions = glob(APPROOT.'data/transactions/'.self::GetUserPrefix().'*'); $aTransactions = glob(utils::GetDataPath().'transactions/'.self::GetUserPrefix().'*');
foreach($aTransactions as $sFileName) foreach($aTransactions as $sFileName)
{ {
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName); $aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);

View File

@@ -249,9 +249,9 @@ class appUserPreferences extends DBObject
( (
"category" => "gui", "category" => "gui",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "userid", "name_attcode" => "login",
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => array("userid"), "reconc_keys" => array("userid","login"),
"db_table" => "priv_app_preferences", "db_table" => "priv_app_preferences",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
@@ -260,8 +260,10 @@ class appUserPreferences extends DBObject
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributePropertySet("preferences", array("allowed_values"=>null, "sql"=>"preferences", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributePropertySet("preferences", array("allowed_values"=>null, "sql"=>"preferences", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_SetZListItems('list', array('preferences',)); MetaModel::Init_AddAttribute(new AttributeExternalField("org_id", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "org_id")));
MetaModel::Init_SetZListItems('default_search', array('userid')); MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
MetaModel::Init_SetZListItems('list', array('org_id','preferences'));
MetaModel::Init_SetZListItems('default_search', array('userid','login','org_id'));
} }
/** /**

View File

@@ -180,6 +180,7 @@ class utils
*/ */
private static $sAbsoluteUrlAppRootCache = null; private static $sAbsoluteUrlAppRootCache = null;
protected static function LoadParamFile($sParamFile) protected static function LoadParamFile($sParamFile)
{ {
if (!file_exists($sParamFile)) { if (!file_exists($sParamFile)) {
@@ -418,11 +419,26 @@ class utils
* @since 2.7.7, 3.0.2, 3.1.0 N°4899 - new 'url' filter * @since 2.7.7, 3.0.2, 3.1.0 N°4899 - new 'url' filter
* @since 2.7.10 N°6606 use the utils::ENUM_SANITIZATION_* const * @since 2.7.10 N°6606 use the utils::ENUM_SANITIZATION_* const
* @since 2.7.10 N°6606 new case for ENUM_SANITIZATION_FILTER_PHP_CLASS * @since 2.7.10 N°6606 new case for ENUM_SANITIZATION_FILTER_PHP_CLASS
* @since 3.2.1-1 N°8242 Allow value to be an array for every filter
* *
* @link https://www.php.net/manual/en/filter.filters.sanitize.php PHP sanitization filters * @link https://www.php.net/manual/en/filter.filters.sanitize.php PHP sanitization filters
*/ */
protected static function Sanitize_Internal($value, $sSanitizationFilter) protected static function Sanitize_Internal($value, $sSanitizationFilter)
{ {
if (is_array($value))
{
$retValue = array();
foreach ($value as $key => $val)
{
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays
if ($retValue[$key] === false)
{
return false;
}
}
return $retValue;
}
switch ($sSanitizationFilter) switch ($sSanitizationFilter)
{ {
case static::ENUM_SANITIZATION_FILTER_INTEGER: case static::ENUM_SANITIZATION_FILTER_INTEGER:
@@ -453,52 +469,36 @@ class utils
case static::ENUM_SANITIZATION_FILTER_PARAMETER: case static::ENUM_SANITIZATION_FILTER_PARAMETER:
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME: case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID: case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
if (is_array($value)) switch ($sSanitizationFilter)
{ {
$retValue = array(); case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
foreach ($value as $key => $val) // Same as parameter type but keep the dot character
{ // transaction_id, the dot is mostly for Windows servers when using file storage as the tokens are named *.tmp
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays // - See N°1835
if ($retValue[$key] === false) // - Note: It must be included at the regexp beginning otherwise you'll get an invalid character error
{ $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
$retValue = false; break;
break;
}
}
}
else
{
switch ($sSanitizationFilter)
{
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
// Same as parameter type but keep the dot character
// transaction_id, the dot is mostly for Windows servers when using file storage as the tokens are named *.tmp
// - See N°1835
// - Note: It must be included at the regexp beginning otherwise you'll get an invalid character error
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_ROUTE: case static::ENUM_SANITIZATION_FILTER_ROUTE:
case static::ENUM_SANITIZATION_FILTER_OPERATION: case static::ENUM_SANITIZATION_FILTER_OPERATION:
// - Routes should be of the "controller_namespace_code.controller_method_name" form // - Routes should be of the "controller_namespace_code.controller_method_name" form
// - Operations should be allowed to be namespaced as well even though then don't have dedicated controller yet // - Operations should be allowed to be namespaced as well even though then don't have dedicated controller yet
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\.A-Za-z0-9_-]*$/'))); $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\.A-Za-z0-9_-]*$/')));
break; break;
case static::ENUM_SANITIZATION_FILTER_PARAMETER: case static::ENUM_SANITIZATION_FILTER_PARAMETER:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F' $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
// Characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC) // Characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
break; break;
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME: case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
break; break;
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM: case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/'))); $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
break; break;
}
} }
break; break;
@@ -1451,9 +1451,12 @@ class utils
* @return string A path to a folder into which any module can store cache data * @return string A path to a folder into which any module can store cache data
* The corresponding folder is created or cleaned upon code compilation * The corresponding folder is created or cleaned upon code compilation
*/ */
public static function GetCachePath() public static function GetCachePath(string $sEnvironment = null): string
{ {
return static::GetDataPath().'cache-'.MetaModel::GetEnvironment().'/'; if (is_null($sEnvironment)) {
$sEnvironment = MetaModel::GetEnvironment();
}
return static::GetDataPath()."cache-$sEnvironment/";
} }
/** /**
@@ -1944,7 +1947,7 @@ SQL;
CURLOPT_HEADER => false, // don't return the headers in the output CURLOPT_HEADER => false, // don't return the headers in the output
CURLOPT_FOLLOWLOCATION => true, // follow redirects CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "spider", // who am i CURLOPT_USERAGENT => static::GetConfig()->Get('http.request.user_agent'), // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response CURLOPT_TIMEOUT => 120, // timeout on response
@@ -2390,53 +2393,75 @@ SQL;
return $bRet; return $bRet;
} }
/**
* @param $sPath
*
* @return false|\ormDocument
* @throws \Exception
*
* @deprecated 3.2.1 use utils::GetDocumentFromSelfURL instead
*/
public static function IsSelfURL($sPath)
{
return self::GetDocumentFromSelfURL($sPath);
}
/** /**
* Check if the given URL is a link to download a document/image on the CURRENT iTop * Check if the given URL is a link to download a document/image on the CURRENT iTop
* In such a case we can read the content of the file directly in the database (if the users rights allow) and return the ormDocument * In such a case we can read the content of the file directly in the database (if the users rights allow) and return the ormDocument
*
* @Since 3.2.1 a local URL is transformed into a local file to read
*
* @param string $sPath * @param string $sPath
* @return false|ormDocument * @return false|ormDocument
* @throws Exception * @throws Exception
*/ */
public static function IsSelfURL($sPath) public static function GetDocumentFromSelfURL(string $sPath)
{ {
$result = false;
$sPageUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.document.php'; $sPageUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.document.php';
if (substr($sPath, 0, strlen($sPageUrl)) == $sPageUrl) if (utils::StartsWith($sPath, $sPageUrl)) {
{
// If the URL is an URL pointing to this instance of iTop, then // If the URL is an URL pointing to this instance of iTop, then
// extract the "query" part of the URL and analyze it // extract the "query" part of the URL and analyze it
$sQuery = parse_url($sPath, PHP_URL_QUERY); $sQuery = parse_url($sPath, PHP_URL_QUERY);
if ($sQuery !== null) if ($sQuery !== null) {
{
$aParams = array(); $aParams = array();
foreach(explode('&', $sQuery) as $sChunk) foreach (explode('&', $sQuery) as $sChunk) {
{
$aParts = explode('=', $sChunk ?? ''); $aParts = explode('=', $sChunk ?? '');
if (count($aParts) != 2) continue; if (count($aParts) != 2) {
continue;
}
$aParams[$aParts[0]] = urldecode($aParts[1]); $aParams[$aParts[0]] = urldecode($aParts[1]);
} }
$result = array_key_exists('operation', $aParams) && array_key_exists('class', $aParams) && array_key_exists('id', $aParams) && array_key_exists('field', $aParams) && ($aParams['operation'] == 'download_document'); $result = array_key_exists('operation', $aParams) && array_key_exists('class', $aParams) && array_key_exists('id', $aParams) && array_key_exists('field', $aParams) && ($aParams['operation'] == 'download_document');
if ($result) if ($result) {
{
// This is a 'download_document' operation, let's retrieve the document directly from the database // This is a 'download_document' operation, let's retrieve the document directly from the database
$sClass = $aParams['class']; $sClass = $aParams['class'];
$iKey = $aParams['id']; $iKey = $aParams['id'];
$sAttCode = $aParams['field']; $sAttCode = $aParams['field'];
$oObj = MetaModel::GetObject($sClass, $iKey, false /* must exist */); // Users rights apply here !! $oObj = MetaModel::GetObject($sClass, $iKey, false /* must exist */); // Users rights apply here !!
if ($oObj) if ($oObj) {
{
/** /**
* @var ormDocument $result * @var ormDocument $result
*/ */
$result = clone $oObj->Get($sAttCode); return clone $oObj->Get($sAttCode);
return $result;
} }
} }
} }
throw new Exception('Invalid URL. This iTop URL is not pointing to a valid Document/Image.'); throw new Exception('Invalid URL. This iTop URL is not pointing to a valid Document/Image.');
} }
return $result;
if (utils::StartsWith($sPath, utils::GetAbsoluteUrlAppRoot())) {
$sFilePath = utils::LocalPath(APPROOT.substr($sPath, strlen(utils::GetAbsoluteUrlAppRoot())));
if (false === $sFilePath) {
return false;
}
$sFilePath = APPROOT.$sFilePath;
return ormDocument::FromFile($sFilePath);
}
return false;
} }
/** /**
@@ -2444,68 +2469,28 @@ SQL;
* - an URL pointing to a blob (image/document) on the current iTop server * - an URL pointing to a blob (image/document) on the current iTop server
* - an http(s) URL * - an http(s) URL
* - the local file system (but only if you are an administrator) * - the local file system (but only if you are an administrator)
* @param string $sPath *
* @param string|null $sPath
* @return ormDocument|null * @return ormDocument|null
* @throws Exception * @throws Exception
*/ */
public static function FileGetContentsAndMIMEType($sPath) public static function FileGetContentsAndMIMEType($sPath)
{ {
$oUploadedDoc = null; if (utils::IsNullOrEmptyString($sPath)) {
$aKnownExtensions = array(
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'dot' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'vsd' => 'application/x-visio',
'vdx' => 'application/visio.drawing',
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'zip' => 'application/zip',
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'exe' => 'application/octet-stream',
);
$sData = null;
$sMimeType = 'text/plain'; // Default MIME Type: treat the file as a bunch a characters...
$sFileName = 'uploaded-file'; // Default name for downloaded-files
$sExtension = '.txt'; // Default file extension in case we don't know the MIME Type
if(empty($sPath))
{
// Empty path (NULL or '') means that there is no input, making an empty document. // Empty path (NULL or '') means that there is no input, making an empty document.
$oUploadedDoc = new ormDocument('', '', ''); return new ormDocument('', '', '');
} }
elseif (static::IsURL($sPath))
{ if (static::IsURL($sPath)) {
if ($oUploadedDoc = static::IsSelfURL($sPath)) $oUploadedDoc = static::GetDocumentFromSelfURL($sPath);
{ if ($oUploadedDoc) {
// Nothing more to do, we've got it !! return $oUploadedDoc;
} }
else
{ // Remote file, let's use the HTTP headers to find the MIME Type
// Remote file, let's use the HTTP headers to find the MIME Type $sData = @file_get_contents($sPath);
$sData = @file_get_contents($sPath); if ($sData === false) {
if ($sData === false) IssueLog::Error(<<<TXT
{
IssueLog::Error(<<<TXT
Failed to load the file from URL. This can happen for multiple reasons: Failed to load the file from URL. This can happen for multiple reasons:
- Invalid URL - Invalid URL
- URL using HTTPS with an untrusted certificate on the remote server - URL using HTTPS with an untrusted certificate on the remote server
@@ -2514,54 +2499,40 @@ TXT
, LogChannels::CORE, [ , LogChannels::CORE, [
'URL' => $sPath, 'URL' => $sPath,
]); ]);
throw new Exception("Failed to load the file from the URL '$sPath'."); throw new Exception("Failed to load the file from the URL '$sPath'.");
}
else
{
if (isset($http_response_header))
{
$aHeaders = static::ParseHeaders($http_response_header);
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
// Compute the file extension from the MIME Type
foreach ($aKnownExtensions as $sExtValue => $sMime) {
if ($sMime === $sMimeType) {
$sExtension = '.'.$sExtValue;
break;
}
}
}
$sPathName = pathinfo($sPath, PATHINFO_FILENAME);
if (utils::IsNotNullOrEmptyString($sPathName)) {
$sFileName = $sPathName;
}
$sFileName .= $sExtension;
}
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
} }
}
else if (UserRights::IsAdministrator())
{
// Only administrators are allowed to read local files
$sData = @file_get_contents($sPath);
if ($sData === false)
{
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
}
$sExtension = strtolower(pathinfo($sPath, PATHINFO_EXTENSION));
$sFileName = basename($sPath);
if (array_key_exists($sExtension, $aKnownExtensions)) $sMimeType = 'text/plain'; // Default MIME Type: treat the file as a bunch a characters...
{ $sFileName = 'uploaded-file'; // Default name for downloaded-files
$sMimeType = $aKnownExtensions[$sExtension]; $sExtension = '.txt'; // Default file extension in case we don't know the MIME Type
if (isset($http_response_header)) {
$aHeaders = static::ParseHeaders($http_response_header);
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
// Compute the file extension from the MIME Type
foreach (ormDocument::GetKnownExtensions() as $sExtValue => $sMime) {
if ($sMime === $sMimeType) {
$sExtension = '.'.$sExtValue;
break;
}
}
} }
else if (extension_loaded('fileinfo')) $sPathName = pathinfo($sPath, PATHINFO_FILENAME);
{ if (utils::IsNotNullOrEmptyString($sPathName)) {
$finfo = new finfo(FILEINFO_MIME); $sFileName = $sPathName;
$sMimeType = $finfo->file($sPath);
} }
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName); $sFileName .= $sExtension;
return new ormDocument($sData, $sMimeType, $sFileName);
} }
return $oUploadedDoc;
// Local file
if (UserRights::IsAdministrator()) {
// Only administrators are allowed to read local files
return ormDocument::FromFile($sPath);
}
return null;
} }
protected static function ParseHeaders($aHeaders) protected static function ParseHeaders($aHeaders)
@@ -3132,30 +3103,13 @@ TXT
* @throws \Exception * @throws \Exception
* @since 3.0.0 * @since 3.0.0
*/ */
public static function GetMentionedObjectsFromText(string $sText, string $sFormat = self::ENUM_TEXT_FORMAT_HTML): array public static function GetMentionedObjectsFromText(string $sText): array
{ {
// First transform text so it can be parsed $aMentionedObjects = [];
switch ($sFormat) { $aMentionMatches = [];
case static::ENUM_TEXT_FORMAT_HTML: $sText = html_entity_decode($sText);
$sText = static::HtmlToText($sText);
break;
default:
// Don't transform it
break;
}
// Then parse text to find objects
$aMentionedObjects = array();
$aMentionMatches = array();
// Note: As the sanitizer (or CKEditor autocomplete plugin? 🤔) removes data-* attributes from the hyperlink,
// - we can't use the following (simpler) regexp that only checks data attributes on hyperlinks, which would have worked for hyperlinks pointing to any GUIs: '/<a\s*([^>]*)data-object-class="([^"]*)"\s*data-object-id="([^"]*)">/i'
// - instead we use a regexp to match the following pattern '[Some object label](<APP_ROOT_URL>...&class=<OBJECT_CLASS>&id=<OBJECT_ID>...)' which only works for the backoffice
// If we change the sanitizer, we might want to switch to the other regexp as it's universal and easier to read
$sAppRootUrlForRegExp = addcslashes(utils::GetAbsoluteUrlAppRoot(), '/&');
preg_match_all("/\[([^\]]*)\]\({$sAppRootUrlForRegExp}[^\)]*\&class=([^\)\&]*)\&id=([\d]*)[^\)]*\)/i", $sText, $aMentionMatches);
preg_match_all('/<a\s*([^>]*)data-object-class="([^"]*)"\s.*data-object-key="([^"]*)"/Ui', $sText, $aMentionMatches);
foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) { foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) {
$sMatchedClass = $aMentionMatches[2][$iMatchIdx]; $sMatchedClass = $aMentionMatches[2][$iMatchIdx];
$sMatchedId = $aMentionMatches[3][$iMatchIdx]; $sMatchedId = $aMentionMatches[3][$iMatchIdx];

View File

@@ -11,7 +11,7 @@ define('APPCONF', APPROOT.'conf/');
* *
* @see ITOP_CORE_VERSION to get full iTop core version * @see ITOP_CORE_VERSION to get full iTop core version
*/ */
define('ITOP_DESIGN_LATEST_VERSION', '3.2'); define('ITOP_DESIGN_LATEST_VERSION', '3.3');
/** /**
* Constant containing the iTop core version, whatever application was built * Constant containing the iTop core version, whatever application was built
@@ -23,7 +23,7 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.2');
* @used-by utils::GetItopVersionWikiSyntax() * @used-by utils::GetItopVersionWikiSyntax()
* @used-by iTopModulesPhpVersionIntegrationTest * @used-by iTopModulesPhpVersionIntegrationTest
*/ */
define('ITOP_CORE_VERSION', '3.2.0'); define('ITOP_CORE_VERSION', '3.3.0');
/** /**
* @var string * @var string

102
composer.lock generated
View File

@@ -3929,6 +3929,82 @@
], ],
"time": "2023-01-26T09:26:14+00:00" "time": "2023-01-26T09:26:14+00:00"
}, },
{
"name": "symfony/polyfill-php81",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php81\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{ {
"name": "symfony/polyfill-php83", "name": "symfony/polyfill-php83",
"version": "v1.28.0", "version": "v1.28.0",
@@ -4976,30 +5052,38 @@
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
"version": "v3.8.0", "version": "v3.16.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twigphp/Twig.git", "url": "https://github.com/twigphp/Twig.git",
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" "reference": "475ad2dc97d65d8631393e721e7e44fb544f0561"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", "url": "https://api.github.com/repos/twigphp/Twig/zipball/475ad2dc97d65d8631393e721e7e44fb544f0561",
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", "reference": "475ad2dc97d65d8631393e721e7e44fb544f0561",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.2.5", "php": ">=8.0.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8", "symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3", "symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php80": "^1.22" "symfony/polyfill-php81": "^1.29"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "^2.0",
"psr/container": "^1.0|^2.0", "psr/container": "^1.0|^2.0",
"symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"files": [
"src/Resources/core.php",
"src/Resources/debug.php",
"src/Resources/escaper.php",
"src/Resources/string_loader.php"
],
"psr-4": { "psr-4": {
"Twig\\": "src/" "Twig\\": "src/"
} }
@@ -5032,7 +5116,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/twigphp/Twig/issues", "issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.8.0" "source": "https://github.com/twigphp/Twig/tree/v3.16.0"
}, },
"funding": [ "funding": [
{ {
@@ -5044,7 +5128,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-11-21T18:54:41+00:00" "time": "2024-11-29T08:27:05+00:00"
}, },
{ {
"name": "webmozart/assert", "name": "webmozart/assert",

View File

@@ -181,7 +181,7 @@ abstract class Action extends cmdbAbstractObject
{ {
parent::DisplayBareRelations($oPage, false); parent::DisplayBareRelations($oPage, false);
if ($oPage instanceof iTopWebPage) { if ($oPage instanceof iTopWebPage && !$this->IsNew()) {
$this->GenerateLastExecutionsTab($oPage, $bEditMode); $this->GenerateLastExecutionsTab($oPage, $bEditMode);
} }
} }
@@ -566,6 +566,7 @@ class ActionEmail extends ActionNotification
$oLog->Set('trigger_id', $oTrigger->GetKey()); $oLog->Set('trigger_id', $oTrigger->GetKey());
$oLog->Set('action_id', $this->GetKey()); $oLog->Set('action_id', $this->GetKey());
$oLog->Set('object_id', $aContextArgs['this->object()']->GetKey()); $oLog->Set('object_id', $aContextArgs['this->object()']->GetKey());
$oLog->Set('object_class', get_class($aContextArgs['this->object()']));
// Must be inserted now so that it gets a valid id that will make the link // Must be inserted now so that it gets a valid id that will make the link
// between an eventual asynchronous task (queued) and the log // between an eventual asynchronous task (queued) and the log
$oLog->DBInsertNoReload(); $oLog->DBInsertNoReload();

View File

@@ -89,7 +89,7 @@ abstract class AsyncTask extends DBObject
// The value is set from null to planned in the setup program // The value is set from null to planned in the setup program
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('planned,running,idle,error'), "sql"=>"status", "default_value"=>"planned", "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('planned,running,idle,error'), "sql"=>"status", "default_value"=>"planned", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("started", array("allowed_values"=>null, "sql"=>"started", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("started", array("allowed_values"=>null, "sql"=>"started", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("planned", array("allowed_values"=>null, "sql"=>"planned", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("planned", array("allowed_values"=>null, "sql"=>"planned", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("event_id", array("targetclass"=>"Event", "jointype"=> "", "allowed_values"=>null, "sql"=>"event_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_SILENT, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("event_id", array("targetclass"=>"Event", "jointype"=> "", "allowed_values"=>null, "sql"=>"event_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
@@ -489,7 +489,7 @@ class AsyncSendNewsroom extends AsyncTask {
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values"=>null, "sql"=>"object_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values"=>null, "sql"=>"object_id", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("object_class", array("allowed_values"=>null, "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("object_class", array("allowed_values"=>null, "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("url", array("allowed_values"=>null, "sql"=>"url", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeText("url", array("allowed_values"=>null, "sql"=>"url", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>null, "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>'NOW()', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
} }

View File

@@ -142,7 +142,7 @@ abstract class AttributeDefinition
protected $aCSSClasses; protected $aCSSClasses;
public function GetType() public function GetType()
{ {
return Dict::S('Core:'.get_class($this)); return Dict::S('Core:'.get_class($this));
} }
@@ -181,6 +181,23 @@ abstract class AttributeDefinition
return $this->GetSearchType() != static::SEARCH_WIDGET_TYPE_RAW; return $this->GetSearchType() != static::SEARCH_WIDGET_TYPE_RAW;
} }
/**
* @return bool
*/
public function IsComputed()
{
return $this->IsParam('expression');
}
/**
* @return array
* @throws \OQLException
*/
protected function GetComputedPrerequisiteAttributes(): array {
$oExpression = Expression::FromOQL($this->m_aParams['expression']);
return $oExpression->ListRequiredFields();
}
/** @var string */ /** @var string */
protected $m_sCode; protected $m_sCode;
/** @var array */ /** @var array */
@@ -1715,8 +1732,8 @@ class AttributeLinkedSet extends AttributeDefinition
public function GetEditMode() public function GetEditMode()
{ {
return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS); return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS);
} }
/** /**
* @return int see LINKSET_EDITWHEN_* constants * @return int see LINKSET_EDITWHEN_* constants
* @since 3.1.1 3.2.0 N°6385 * @since 3.1.1 3.2.0 N°6385
@@ -1758,7 +1775,7 @@ class AttributeLinkedSet extends AttributeDefinition
{ {
return $this->GetOptional('with_php_computation', false); return $this->GetOptional('with_php_computation', false);
} }
public function GetLinkedClass() public function GetLinkedClass()
{ {
return $this->Get('linked_class'); return $this->Get('linked_class');
@@ -2717,7 +2734,11 @@ class AttributeDBFieldVoid extends AttributeDefinition
public function GetPrerequisiteAttributes($sClass = null) public function GetPrerequisiteAttributes($sClass = null)
{ {
return $this->Get("depends_on"); $aPrerequisiteAttributes = $this->Get("depends_on");
if($this->IsComputed()) {
$aPrerequisiteAttributes = array_merge($aPrerequisiteAttributes, $this->GetComputedPrerequisiteAttributes());
}
return $aPrerequisiteAttributes;
} }
public static function IsBasedOnDBColumns() public static function IsBasedOnDBColumns()
@@ -2732,7 +2753,7 @@ class AttributeDBFieldVoid extends AttributeDefinition
public function IsWritable() public function IsWritable()
{ {
return !$this->IsMagic(); return !$this->IsMagic() && !$this->IsComputed();
} }
public function GetSQLExpr() public function GetSQLExpr()
@@ -2962,14 +2983,12 @@ class AttributeInteger extends AttributeDBField
public function MakeRealValue($proposedValue, $oHostObj) public function MakeRealValue($proposedValue, $oHostObj)
{ {
if (is_null($proposedValue)) if (is_null($proposedValue) || $proposedValue === '')
{ {
return null; return null;
} elseif(gettype($proposedValue) !== 'integer') {
IssueLog::Warning("Trying to set integer attribute ".$this->GetCode()." to type".gettype($proposedValue).".");
} }
if ($proposedValue === '')
{
return null;
} // 0 is transformed into '' !
return (int)$proposedValue; return (int)$proposedValue;
} }
@@ -3793,7 +3812,7 @@ class AttributeClass extends AttributeString
public static function ListExpectedParams() public static function ListExpectedParams()
{ {
return array_merge(parent::ListExpectedParams(), array("class_category", "more_values")); return array_merge(parent::ListExpectedParams(), array('class_category', 'more_values'));
} }
public function __construct($sCode, $aParams) public function __construct($sCode, $aParams)
@@ -3819,10 +3838,35 @@ class AttributeClass extends AttributeString
return $sDefault; return $sDefault;
} }
/**
* @param array $aArgs
* @param string $sContains
*
* @return array|null
* @throws \CoreException
*/
public function GetAllowedValues($aArgs = array(), $sContains = '')
{
$oValSetDef = $this->GetValuesDef();
if (!$oValSetDef) {
return null;
}
$aListClass = $oValSetDef->GetValues($aArgs, $sContains);
/* @since 3.3.0 remove elements in class_exclusion_list*/
$sClassExclusionList = $this->GetOptional('class_exclusion_list',null);
if (!empty($sClassExclusionList)) {
foreach (explode(',', $sClassExclusionList) as $sClassName) {
unset($aListClass[trim($sClassName)]);
}
}
return $aListClass;
}
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true) public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
{ {
if (empty($sValue)) if (empty($sValue)) {
{
return ''; return '';
} }
@@ -4193,7 +4237,7 @@ class AttributeFinalClass extends AttributeString
*/ */
class AttributePassword extends AttributeString implements iAttributeNoGroupBy class AttributePassword extends AttributeString implements iAttributeNoGroupBy
{ {
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW; const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
/** /**
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329) * Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)
@@ -4270,7 +4314,7 @@ class AttributePassword extends AttributeString implements iAttributeNoGroupBy
*/ */
class AttributeEncryptedString extends AttributeString implements iAttributeNoGroupBy class AttributeEncryptedString extends AttributeString implements iAttributeNoGroupBy
{ {
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW; const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
protected function GetSQLCol($bFullSpec = false) protected function GetSQLCol($bFullSpec = false)
{ {
@@ -4440,7 +4484,7 @@ class AttributeText extends AttributeString
{ {
// Is there a way to know the current limitation for mysql? // Is there a way to know the current limitation for mysql?
// See mysql_field_len() // See mysql_field_len()
return 65535; return 16383; // number of characters (that can be 1-4 bytes long), not of bytes
} }
public static function RenderWikiHtml($sText, $bWikiOnly = false) public static function RenderWikiHtml($sText, $bWikiOnly = false)
@@ -6346,10 +6390,15 @@ class AttributeDateTime extends AttributeDBField
$oFormField = parent::MakeFormField($oObject, $oFormField); $oFormField = parent::MakeFormField($oObject, $oFormField);
// After call to the parent as it sets the current value // After call to the parent as it sets the current value
$oFormField->SetCurrentValue($this->GetFormat()->Format($oObject->Get($this->GetCode()))); $oValue = $oObject->Get($this->GetCode());
if ($oValue === $this->GetNullValue()) {
$oValue = $this->GetDefaultValue($oObject);
}
$oFormField->SetCurrentValue($this->GetFormat()->Format($oValue));
return $oFormField;
return $oFormField;
} }
/** /**
@@ -6433,8 +6482,26 @@ class AttributeDateTime extends AttributeDBField
public function GetDefaultValue(DBObject $oHostObject = null) public function GetDefaultValue(DBObject $oHostObject = null)
{ {
if (!$this->IsNullAllowed()) { $sDefaultValue = $this->Get('default_value');
return date($this->GetInternalFormat()); if (utils::IsNotNullOrEmptyString($sDefaultValue)) {
try {
$sDefaultDate = Expression::FromOQL($sDefaultValue)->Evaluate([]);
} catch (Exception $e) {
try {
$sDefaultDate = Expression::FromOQL('"'.$sDefaultValue.'"')->Evaluate([]);
} catch (Exception $e) {
IssueLog::Error("Invalid default value '$sDefaultValue' for field '{$this->GetCode()}' on class '{$this->GetHostClass()}', defaulting to null");
return $this->GetNullValue();
}
}
try {
$oDate = new DateTimeImmutable($sDefaultDate);
} catch (Exception $e) {
IssueLog::Error("Invalid default value '$sDefaultValue' for field '{$this->GetCode()}' on class '{$this->GetHostClass()}', defaulting to null");
return $this->GetNullValue();
}
return $oDate->format($this->GetInternalFormat());
} }
return $this->GetNullValue(); return $this->GetNullValue();
} }
@@ -9433,8 +9500,13 @@ class AttributeStopWatch extends AttributeDefinition
case 'deadline': case 'deadline':
if ($value) if ($value)
{ {
$sDate = date(AttributeDateTime::GetInternalFormat(), $value); if (is_int($value))
$sRet = AttributeDeadline::FormatDeadline($sDate); {
$sDate = date(AttributeDateTime::GetInternalFormat(), $value);
$sRet = AttributeDeadline::FormatDeadline($sDate);
} else {
$sRet = $value;
}
} }
else else
{ {
@@ -9984,7 +10056,7 @@ class AttributeSubItem extends AttributeDefinition
*/ */
class AttributeOneWayPassword extends AttributeDefinition implements iAttributeNoGroupBy class AttributeOneWayPassword extends AttributeDefinition implements iAttributeNoGroupBy
{ {
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW; const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
/** /**
* Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329) * Useless constructor, but if not present PHP 7.4.0/7.4.1 is crashing :( (N°2329)

View File

@@ -519,7 +519,7 @@ class BulkChange
foreach ($this->m_aExtKeys[$sAttCode] as $sForeignAttCode => $iCol) foreach ($this->m_aExtKeys[$sAttCode] as $sForeignAttCode => $iCol)
{ {
// The foreign attribute is one of our reconciliation key // The foreign attribute is one of our reconciliation key
if (strlen($aRowData[$iCol]) > 0) if (isset($aRowData[$iCol]) && strlen($aRowData[$iCol]) > 0)
{ {
return false; return false;
} }
@@ -1181,6 +1181,9 @@ class BulkChange
foreach($this->m_aData as $iRow => $aRowData) foreach($this->m_aData as $iRow => $aRowData)
{ {
$sFormat = $sDateTimeFormat; $sFormat = $sDateTimeFormat;
if(!isset($this->m_aData[$iRow][$iCol])){
continue;
}
$sValue = $this->m_aData[$iRow][$iCol]; $sValue = $this->m_aData[$iRow][$iCol];
if (!empty($sValue)) if (!empty($sValue))
{ {
@@ -1233,11 +1236,22 @@ class BulkChange
$iPreviousTimeLimit = ini_get('max_execution_time'); $iPreviousTimeLimit = ini_get('max_execution_time');
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
$iNBFields = count($this->m_aAttList);
foreach ($this->m_aExtKeys as $aReconcilKeys) {
$iNBFields += count($aReconcilKeys);
}
// Avoid too many events // Avoid too many events
cmdbAbstractObject::SetEventDBLinksChangedBlocked(true); cmdbAbstractObject::SetEventDBLinksChangedBlocked(true);
try { try {
foreach ($this->m_aData as $iRow => $aRowData) { foreach ($this->m_aData as $iRow => $aRowData) {
set_time_limit(intval($iLoopTimeLimit)); set_time_limit(intval($iLoopTimeLimit));
// Stop if not the good number of cols in $aRowData
if(count($aRowData) != $iNBFields){
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::Format('UI:CSVReport-Row-Issue-NbField',count($aRowData),$iNBFields) );
continue;
}
if (isset($aResult[$iRow]["__STATUS__"])) { if (isset($aResult[$iRow]["__STATUS__"])) {
// An issue at the earlier steps - skip the rest // An issue at the earlier steps - skip the rest
continue; continue;
@@ -1348,7 +1362,11 @@ class BulkChange
{ {
if (!array_key_exists($iCol, $aResult[$iRow])) if (!array_key_exists($iCol, $aResult[$iRow]))
{ {
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]); if(isset($aRowData[$iCol])) {
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
} else {
$aResult[$iRow][$iCol] = new CellStatus_Issue('', null, Dict::S('UI:CSVReport-Value-Issue-NoValue'));
}
} }
} }
foreach($this->m_aExtKeys as $sAttCode => $aForeignAtts) foreach($this->m_aExtKeys as $sAttCode => $aForeignAtts)
@@ -1362,7 +1380,11 @@ class BulkChange
if (!array_key_exists($iCol, $aResult[$iRow])) if (!array_key_exists($iCol, $aResult[$iRow]))
{ {
// The foreign attribute is one of our reconciliation key // The foreign attribute is one of our reconciliation key
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]); if(isset($aRowData[$iCol])) {
$aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
} else {
$aResult[$iRow][$iCol] = new CellStatus_Issue('', null, 'UI:CSVReport-Value-Issue-NoValue');
}
} }
} }
} }

View File

@@ -70,7 +70,7 @@ class BulkExportResult extends DBObject
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("allowed_values"=>null, "sql"=>"user_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("allowed_values"=>null, "sql"=>"user_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("chunk_size", array("allowed_values"=>null, "sql"=>"chunk_size", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeInteger("chunk_size", array("allowed_values"=>null, "sql"=>"chunk_size", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("format", array("allowed_values"=>null, "sql"=>"format", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("format", array("allowed_values"=>null, "sql"=>"format", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
@@ -474,14 +474,14 @@ abstract class BulkExport
*/ */
protected function MakeTmpFile($sExtension) protected function MakeTmpFile($sExtension)
{ {
if(!is_dir(APPROOT."data/bulk_export")) if(!is_dir(utils::GetDataPath()."bulk_export"))
{ {
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */); @mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
clearstatcache(); clearstatcache();
} }
if (!is_writable(APPROOT."data/bulk_export")) if (!is_writable(utils::GetDataPath()."bulk_export"))
{ {
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.'); throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
} }
$iNum = rand(); $iNum = rand();
@@ -489,7 +489,7 @@ abstract class BulkExport
{ {
$iNum++; $iNum++;
$sToken = sprintf("%08x", $iNum); $sToken = sprintf("%08x", $iNum);
$sFileName = APPROOT."data/bulk_export/$sToken.".$sExtension; $sFileName = utils::GetDataPath()."bulk_export/$sToken.".$sExtension;
$hFile = @fopen($sFileName, 'x'); $hFile = @fopen($sFileName, 'x');
} }
while($hFile === false); while($hFile === false);

View File

@@ -33,7 +33,7 @@ class CMDBChange extends DBObject
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes(); //MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("allowed_values"=>null, "sql"=>"user_id", "targetclass"=>"User", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("allowed_values"=>null, "sql"=>"user_id", "targetclass"=>"User", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeEnum("origin", array("allowed_values"=>new ValueSetEnum(implode(',', [CMDBChangeOrigin::INTERACTIVE, CMDBChangeOrigin::CSV_INTERACTIVE, CMDBChangeOrigin::CSV_IMPORT, CMDBChangeOrigin::WEBSERVICE_SOAP, CMDBChangeOrigin::WEBSERVICE_REST, CMDBChangeOrigin::SYNCHRO_DATA_SOURCE, CMDBChangeOrigin::EMAIL_PROCESSING, CMDBChangeOrigin::CUSTOM_EXTENSION])), "sql"=>"origin", "default_value"=>CMDBChangeOrigin::INTERACTIVE, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeEnum("origin", array("allowed_values"=>new ValueSetEnum(implode(',', [CMDBChangeOrigin::INTERACTIVE, CMDBChangeOrigin::CSV_INTERACTIVE, CMDBChangeOrigin::CSV_IMPORT, CMDBChangeOrigin::WEBSERVICE_SOAP, CMDBChangeOrigin::WEBSERVICE_REST, CMDBChangeOrigin::SYNCHRO_DATA_SOURCE, CMDBChangeOrigin::EMAIL_PROCESSING, CMDBChangeOrigin::CUSTOM_EXTENSION])), "sql"=>"origin", "default_value"=>CMDBChangeOrigin::INTERACTIVE, "is_null_allowed"=>true, "depends_on"=>array())));

View File

@@ -29,7 +29,7 @@ define('ITOP_APPLICATION_SHORT', 'iTop');
* *
* @see ITOP_CORE_VERSION to get iTop core version * @see ITOP_CORE_VERSION to get iTop core version
*/ */
define('ITOP_VERSION', '3.2.0-dev'); define('ITOP_VERSION', '3.3.0-dev');
define('ITOP_VERSION_NAME', 'Fullmoon'); define('ITOP_VERSION_NAME', 'Fullmoon');
define('ITOP_REVISION', 'svn'); define('ITOP_REVISION', 'svn');
@@ -71,7 +71,7 @@ define('DEFAULT_MAX_DISPLAY_LIMIT', 30);
define('DEFAULT_STANDARD_RELOAD_INTERVAL', 5 * 60); define('DEFAULT_STANDARD_RELOAD_INTERVAL', 5 * 60);
define('DEFAULT_FAST_RELOAD_INTERVAL', 1 * 60); define('DEFAULT_FAST_RELOAD_INTERVAL', 1 * 60);
define('DEFAULT_SECURE_CONNECTION_REQUIRED', false); define('DEFAULT_SECURE_CONNECTION_REQUIRED', false);
define('DEFAULT_ALLOWED_LOGIN_TYPES', 'form|external|basic'); define('DEFAULT_ALLOWED_LOGIN_TYPES', 'form|external|basic|token');
define('DEFAULT_EXT_AUTH_VARIABLE', '$_SERVER[\'REMOTE_USER\']'); define('DEFAULT_EXT_AUTH_VARIABLE', '$_SERVER[\'REMOTE_USER\']');
define('DEFAULT_ENCRYPTION_KEY', '@iT0pEncr1pti0n!'); // We'll use a random generated key later (if possible) define('DEFAULT_ENCRYPTION_KEY', '@iT0pEncr1pti0n!'); // We'll use a random generated key later (if possible)
define('DEFAULT_ENCRYPTION_LIB', 'Mcrypt'); // We'll define the best encryption available later define('DEFAULT_ENCRYPTION_LIB', 'Mcrypt'); // We'll define the best encryption available later
@@ -1436,6 +1436,14 @@ class Config
'quick_create.max_history_results' => [ 'quick_create.max_history_results' => [
'type' => 'integer', 'type' => 'integer',
'description' => 'Max. number of elements in the history', 'description' => 'Max. number of elements in the history',
'default' => 5,
'value' => 5,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'quick_create.max_popular_results' => [
'type' => 'integer',
'description' => 'Max. number of elements in the popular classes section',
'default' => 10, 'default' => 10,
'value' => 10, 'value' => 10,
'source_of_value' => '', 'source_of_value' => '',
@@ -1795,6 +1803,13 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'http.request.user_agent' => [
'type' => 'string',
'description' => 'HTTP request user agent, use this to set a custom agent on external requests.',
'default' => ITOP_APPLICATION.'/'.ITOP_VERSION,
'source_of_value' => '',
'show_in_conf_sample' => false,
]
]; ];
public function IsProperty($sPropCode) public function IsProperty($sPropCode)

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2"> <itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3">
<classes> <classes>
<class id="lnkActionNotificationToContact" _delta="define"> <class id="lnkActionNotificationToContact" _delta="define">
<parent>cmdbAbstractObject</parent> <parent>cmdbAbstractObject</parent>
@@ -99,7 +99,7 @@
</presentation> </presentation>
<methods/> <methods/>
</class> </class>
<class id="ActionNewsroom" _delta="define"> <class id="ActionNewsroom" _delta="define">
<php_parent> <php_parent>
<name>ActionNotification</name> <name>ActionNotification</name>
</php_parent> </php_parent>
@@ -148,7 +148,7 @@
<display_max_height>96</display_max_height> <display_max_height>96</display_max_height>
<storage_max_width>256</storage_max_width> <storage_max_width>256</storage_max_width>
<storage_max_height>256</storage_max_height> <storage_max_height>256</storage_max_height>
<default_image /> <default_image/>
</field> </field>
<field id="priority" xsi:type="AttributeEnum"> <field id="priority" xsi:type="AttributeEnum">
<sql>priority</sql> <sql>priority</sql>
@@ -183,7 +183,7 @@
</field> </field>
<field id="url" xsi:type="AttributeString"> <field id="url" xsi:type="AttributeString">
<sql>url</sql> <sql>url</sql>
<default_value>$this->url()$</default_value> <default_value>$this-&gt;url()$</default_value>
<is_null_allowed>false</is_null_allowed> <is_null_allowed>false</is_null_allowed>
</field> </field>
</fields> </fields>
@@ -355,21 +355,37 @@
} }
} }
if ($bIsAsync === true) { try {
AsyncSendNewsroom::AddToQueue($this->GetKey(), $oTrigger->GetKey(), $aRecipientsIds, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass); if ($bIsAsync === true) {
} else { AsyncSendNewsroom::AddToQueue($this->GetKey(), $oTrigger->GetKey(), $aRecipientsIds, $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
foreach ($aRecipientsIds as $iRecipientId) { } else {
$oEvent = Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService::MakeEventFromAction($this, $iRecipientId, $oTrigger->GetKey(), $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass); foreach ($aRecipientsIds as $iRecipientId) {
$oEvent->DBInsertNoReload(); $oEvent = Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService::MakeEventFromAction($this, $iRecipientId, $oTrigger->GetKey(), $sMessage, $sTitle, $sUrl, $iObjectId, $sObjectClass);
} $oEvent->DBInsertNoReload();
} }
}
} catch (CoreCannotSaveObjectException $e) {
ExceptionLog::LogException($e);
foreach($aRecipientsIds as $iRecipientId) {
$oEvent = Combodo\iTop\Service\Notification\Event\EventNotificationNewsroomService::MakeEventFromAction($this,
$iRecipientId,
$oTrigger->GetKey(),
Dict::S('Core:EventNotificationNewsroom:ErrorOnDBInsert'),
Dict::S('Core:EventNotificationNewsroom:ErrorNotificationNotSent'),
$sUrl,
$iObjectId,
$sObjectClass
);
$oEvent->DBInsertNoReload();
}
}
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null); $this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
} }
]]></code> ]]></code>
</method> </method>
<method id="GetAsynchronousGlobalSetting"> <method id="GetAsynchronousGlobalSetting">
<comment></comment> <comment/>
<static>true</static> <static>true</static>
<access>public</access> <access>public</access>
<code><![CDATA[ <code><![CDATA[
@@ -381,7 +397,7 @@
</method> </method>
</methods> </methods>
</class> </class>
<class id="EventNotificationNewsroom" _delta="define"> <class id="EventNotificationNewsroom" _delta="define">
<php_parent> <php_parent>
<name>EventNotification</name> <name>EventNotification</name>
</php_parent> </php_parent>
@@ -405,7 +421,7 @@
</reconciliation> </reconciliation>
<order> <order>
<columns> <columns>
<column id="date" ascending="false" /> <column id="date" ascending="false"/>
</columns> </columns>
</order> </order>
</properties> </properties>
@@ -419,7 +435,7 @@
<sql>icon</sql> <sql>icon</sql>
<default_value/> <default_value/>
<is_null_allowed>true</is_null_allowed> <is_null_allowed>true</is_null_allowed>
<default_image /> <default_image/>
</field> </field>
<field id="priority" xsi:type="AttributeEnum"> <field id="priority" xsi:type="AttributeEnum">
<sql>priority</sql> <sql>priority</sql>
@@ -501,14 +517,14 @@
</items> </items>
</details> </details>
<summary> <summary>
<items> <items>
<item id="date"> <item id="date">
<rank>10</rank> <rank>10</rank>
</item> </item>
<item id="message"> <item id="message">
<rank>20</rank> <rank>20</rank>
</item> </item>
</items> </items>
</summary> </summary>
<list> <list>
<items> <items>
@@ -850,6 +866,18 @@
<field id="language" xsi:type="AttributeApplicationLanguage"/> <field id="language" xsi:type="AttributeApplicationLanguage"/>
</fields> </fields>
</class> </class>
<class id="Event" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>DBObject</parent>
<properties>
<category>core/cmdb,view_in_gui</category>
</properties>
<fields>
<field id="message" xsi:type="AttributeText"/>
<field id="date" xsi:type="AttributeDateTime"/>
<field id="userinfo" xsi:type="AttributeString"/>
</fields>
</class>
<class id="EventNotification" _delta="define"> <class id="EventNotification" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php --> <!-- Generated by toolkit/export-class-to-meta.php -->
<parent>Event</parent> <parent>Event</parent>
@@ -996,6 +1024,12 @@
<type>string</type> <type>string</type>
<default/> <default/>
</property> </property>
<property id="class_exclusion_list">
<php_param>class_exclusion_list</php_param>
<mandatory>false</mandatory>
<type>string</type>
<default/>
</property>
<property id="min_up"> <property id="min_up">
<php_param>min_up</php_param> <php_param>min_up</php_param>
<mandatory>true</mandatory> <mandatory>true</mandatory>

View File

@@ -212,6 +212,8 @@ abstract class DBObject implements iDisplay
private $aEventListeners = []; private $aEventListeners = [];
private array $aAllowedTransitions = []; private array $aAllowedTransitions = [];
private ?string $sStimulusBeingApplied = null;
/** /**
* DBObject constructor. * DBObject constructor.
* *
@@ -704,6 +706,8 @@ abstract class DBObject implements iDisplay
} }
$this->_Set($sAttCode, $realvalue); $this->_Set($sAttCode, $realvalue);
$this->UpdateDependentComputedAttributes($sAttCode);
$this->UpdateMetaAttributes(array($sAttCode)); $this->UpdateMetaAttributes(array($sAttCode));
// The object has changed, reset caches // The object has changed, reset caches
@@ -758,10 +762,10 @@ abstract class DBObject implements iDisplay
*/ */
public function SetTrim($sAttCode, $sValue) public function SetTrim($sAttCode, $sValue)
{ {
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode); if (!$this->StringFitsInField($sAttCode, $sValue)) {
$iMaxSize = $oAttDef->GetMaxSize(); $oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
$sLength = mb_strlen($sValue); $iMaxSize = $oAttDef->GetMaxSize();
if ($iMaxSize && ($sLength > $iMaxSize)) { $sLength = mb_strlen($sValue);
$sMessage = " -truncated ($sLength chars)"; $sMessage = " -truncated ($sLength chars)";
$sValue = mb_substr($sValue, 0, $iMaxSize - mb_strlen($sMessage)).$sMessage; $sValue = mb_substr($sValue, 0, $iMaxSize - mb_strlen($sMessage)).$sMessage;
} }
@@ -816,6 +820,24 @@ abstract class DBObject implements iDisplay
$oKPI->ComputeStatsForExtension($this, 'AfterDelete'); $oKPI->ComputeStatsForExtension($this, 'AfterDelete');
} }
/**
* @param string $sAttCode
* @param string $sValue
*
* @return bool
* @throws \Exception
*
* @Since 3.2.2
*/
public function StringFitsInField(string $sAttCode, string $sValue): bool
{
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
$iMaxSize = $oAttDef->GetMaxSize();
$sLength = mb_strlen($sValue);
return !($iMaxSize && ($sLength > $iMaxSize));
}
/** /**
* Compute (and optionally start) the StopWatches deadlines * Compute (and optionally start) the StopWatches deadlines
* *
@@ -1206,7 +1228,7 @@ abstract class DBObject implements iDisplay
if ($aCallInfo["function"] != "ComputeValues") continue; if ($aCallInfo["function"] != "ComputeValues") continue;
return; //skip! return; //skip!
} }
$this->FireEventComputeValues(); $this->FireEventComputeValues($this->sStimulusBeingApplied);
$oKPI = new ExecutionKPI(); $oKPI = new ExecutionKPI();
$this->ComputeValues(); $this->ComputeValues();
$oKPI->ComputeStatsForExtension($this, 'ComputeValues'); $oKPI->ComputeStatsForExtension($this, 'ComputeValues');
@@ -2130,7 +2152,7 @@ abstract class DBObject implements iDisplay
return "Bad type"; return "Bad type";
} }
elseif (($oAtt instanceof AttributeClassAttCodeSet) || ($oAtt instanceof AttributeEnumSet)) elseif ($oAtt instanceof AttributeSet)
{ {
if (is_string($toCheck)) if (is_string($toCheck))
{ {
@@ -2669,7 +2691,7 @@ abstract class DBObject implements iDisplay
// Ultimate check - ensure DB integrity // Ultimate check - ensure DB integrity
$this->SetReadOnly('No modification allowed during CheckToCreate'); $this->SetReadOnly('No modification allowed during CheckToCreate');
$this->FireEventCheckToWrite(); $this->FireEventCheckToWrite($this->sStimulusBeingApplied);
$this->SetReadWrite(); $this->SetReadWrite();
$oKPI = new ExecutionKPI(); $oKPI = new ExecutionKPI();
@@ -2865,6 +2887,14 @@ abstract class DBObject implements iDisplay
protected function ListChangedValues(array $aProposal) protected function ListChangedValues(array $aProposal)
{ {
$aDelta = array(); $aDelta = array();
$sClass = get_class($this);
if (MetaModel::HasLifecycle($sClass) && utils::IsNotNullOrEmptyString($this->sStimulusBeingApplied)) {
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
if (!in_array($sStateAttCode, $aProposal)) {
// Same state but the transition was asked, act as if the state was changed
$aDelta[$sStateAttCode] = $this->m_aCurrValues[$sStateAttCode];
}
}
foreach ($aProposal as $sAtt => $proposedValue) foreach ($aProposal as $sAtt => $proposedValue)
{ {
if (!array_key_exists($sAtt, $this->m_aOrigValues)) if (!array_key_exists($sAtt, $this->m_aOrigValues))
@@ -3398,7 +3428,7 @@ abstract class DBObject implements iDisplay
$this->OnInsert(); $this->OnInsert();
$oKPI->ComputeStatsForExtension($this, 'OnInsert'); $oKPI->ComputeStatsForExtension($this, 'OnInsert');
$this->FireEventBeforeWrite(); $this->FireEventBeforeWrite(null);
// If not automatically computed, then check that the key is given by the caller // If not automatically computed, then check that the key is given by the caller
if (!MetaModel::IsAutoIncrementKey($sRootClass)) { if (!MetaModel::IsAutoIncrementKey($sRootClass)) {
@@ -3533,7 +3563,7 @@ abstract class DBObject implements iDisplay
*/ */
protected function PostInsertActions(): void protected function PostInsertActions(): void
{ {
$this->FireEventAfterWrite([], true); $this->FireEventAfterWrite([], true, null);
$oKPI = new ExecutionKPI(); $oKPI = new ExecutionKPI();
$this->AfterInsert(); $this->AfterInsert();
$oKPI->ComputeStatsForExtension($this, 'AfterInsert'); $oKPI->ComputeStatsForExtension($this, 'AfterInsert');
@@ -3614,13 +3644,13 @@ abstract class DBObject implements iDisplay
*/ */
public function DBUpdate() public function DBUpdate()
{ {
$this->LogCRUDEnter(__METHOD__);
if (!MetaModel::StartReentranceProtection($this)) { if (!MetaModel::StartReentranceProtection($this)) {
$this->LogCRUDExit(__METHOD__, 'Rejected (reentrance)'); $this->LogCRUDExit(__METHOD__, 'Rejected (reentrance)');
return false; return false;
} }
$this->LogCRUDEnter(__METHOD__);
if (!$this->m_bIsInDB) if (!$this->m_bIsInDB)
{ {
throw new CoreException("DBUpdate: could not update a newly created object, please call DBInsert instead"); throw new CoreException("DBUpdate: could not update a newly created object, please call DBInsert instead");
@@ -3641,7 +3671,7 @@ abstract class DBObject implements iDisplay
$this->OnUpdate(); $this->OnUpdate();
$oKPI->ComputeStatsForExtension($this, 'OnUpdate'); $oKPI->ComputeStatsForExtension($this, 'OnUpdate');
$this->FireEventBeforeWrite(); $this->FireEventBeforeWrite($this->sStimulusBeingApplied);
// Freeze the changes at this point // Freeze the changes at this point
$this->InitPreviousValuesForUpdatedAttributes(); $this->InitPreviousValuesForUpdatedAttributes();
@@ -3809,7 +3839,7 @@ abstract class DBObject implements iDisplay
} }
try { try {
$this->PostUpdateActions($aChanges, $sClass); $this->PostUpdateActions($this->m_aPreviousValuesForUpdatedAttributes, $sClass);
} }
catch (Exception $e) { catch (Exception $e) {
$this->LogCRUDExit(__METHOD__, 'Error: '.$e->getMessage()); $this->LogCRUDExit(__METHOD__, 'Error: '.$e->getMessage());
@@ -3852,7 +3882,9 @@ abstract class DBObject implements iDisplay
*/ */
protected function PostUpdateActions(array $aChanges): void protected function PostUpdateActions(array $aChanges): void
{ {
$this->FireEventAfterWrite($aChanges, false); $sStimulusBeingApplied = $this->sStimulusBeingApplied;
$this->sStimulusBeingApplied = null;
$this->FireEventAfterWrite($aChanges, false, $sStimulusBeingApplied);
$oKPI = new ExecutionKPI(); $oKPI = new ExecutionKPI();
$this->AfterUpdate(); $this->AfterUpdate();
$oKPI->ComputeStatsForExtension($this, 'AfterUpdate'); $oKPI->ComputeStatsForExtension($this, 'AfterUpdate');
@@ -3864,39 +3896,37 @@ abstract class DBObject implements iDisplay
$this->ActivateOnObjectUpdateTriggersForTargetObjects(); $this->ActivateOnObjectUpdateTriggersForTargetObjects();
$sClass = get_class($this); $sClass = get_class($this);
if (MetaModel::HasLifecycle($sClass)) if (utils::IsNotNullOrEmptyString($sStimulusBeingApplied))
{ {
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass); $sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
if (isset($this->m_aPreviousValuesForUpdatedAttributes[$sStateAttCode])) { $sPreviousState = $this->m_aPreviousValuesForUpdatedAttributes[$sStateAttCode];
$sPreviousState = $this->m_aPreviousValuesForUpdatedAttributes[$sStateAttCode]; // Change state triggers...
// Change state triggers... $aParams = array(
$aParams = array( 'class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL),
'class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL), 'previous_state' => $sPreviousState,
'previous_state' => $sPreviousState, 'new_state' => $this->Get($sStateAttCode),
'new_state' => $this->Get($sStateAttCode), );
); $oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateLeave AS t WHERE t.target_class IN (:class_list) AND t.state=:previous_state'), array(), $aParams);
$oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateLeave AS t WHERE t.target_class IN (:class_list) AND t.state=:previous_state'), array(), $aParams); while ($oTrigger = $oSet->Fetch()) {
while ($oTrigger = $oSet->Fetch()) { /** @var \TriggerOnStateLeave $oTrigger */
/** @var \TriggerOnStateLeave $oTrigger */ try {
try { $oTrigger->DoActivate($this->ToArgs('this'));
$oTrigger->DoActivate($this->ToArgs('this'));
}
catch (Exception $e) {
$oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e);
}
} }
catch (Exception $e) {
$oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e);
}
}
$oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateEnter AS t WHERE t.target_class IN (:class_list) AND t.state=:new_state'), array(), $aParams); $oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT TriggerOnStateEnter AS t WHERE t.target_class IN (:class_list) AND t.state=:new_state'), array(), $aParams);
while ($oTrigger = $oSet->Fetch()) { while ($oTrigger = $oSet->Fetch()) {
/** @var \TriggerOnStateEnter $oTrigger */ /** @var \TriggerOnStateEnter $oTrigger */
try { try {
$oTrigger->DoActivate($this->ToArgs('this')); $oTrigger->DoActivate($this->ToArgs('this'));
} }
catch (Exception $e) { catch (Exception $e) {
$oTrigger->LogException($e, $this); $oTrigger->LogException($e, $this);
utils::EnrichRaisedException($oTrigger, $e); utils::EnrichRaisedException($oTrigger, $e);
}
} }
} }
} }
@@ -4024,7 +4054,7 @@ abstract class DBObject implements iDisplay
foreach ($aUpdatedLogAttCodes as $sAttCode) { foreach ($aUpdatedLogAttCodes as $sAttCode) {
/** @var \ormCaseLog $oUpdatedCaseLog */ /** @var \ormCaseLog $oUpdatedCaseLog */
$oUpdatedCaseLog = $this->Get($sAttCode); $oUpdatedCaseLog = $this->Get($sAttCode);
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry())); $aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry(ormCaseLog::ENUM_FORMAT_HTML)));
} }
// 3 - Trigger for those objects // 3 - Trigger for those objects
@@ -4501,6 +4531,8 @@ abstract class DBObject implements iDisplay
*/ */
public function ApplyStimulus($sStimulusCode, $bDoNotWrite = false) public function ApplyStimulus($sStimulusCode, $bDoNotWrite = false)
{ {
$this->LogCRUDEnter(__METHOD__, "Code: $sStimulusCode");
$sClass = get_class($this); $sClass = get_class($this);
if (!MetaModel::HasLifecycle($sClass)) if (!MetaModel::HasLifecycle($sClass))
{ {
@@ -4527,6 +4559,8 @@ abstract class DBObject implements iDisplay
} else { } else {
$aBackupValues[$sAttCode] = $value; $aBackupValues[$sAttCode] = $value;
} }
} else {
$aBackupValues[$sAttCode] = $oAttDef->GetNullValue();
} }
} }
@@ -4534,7 +4568,6 @@ abstract class DBObject implements iDisplay
// Change the state before proceeding to the actions, this is necessary because an action might // Change the state before proceeding to the actions, this is necessary because an action might
// trigger another stimuli (alternative: push the stimuli into a queue) // trigger another stimuli (alternative: push the stimuli into a queue)
$sPreviousState = $this->Get($sStateAttCode);
$sNewState = $aTransitionDef['target_state']; $sNewState = $aTransitionDef['target_state'];
$this->Set($sStateAttCode, $sNewState); $this->Set($sStateAttCode, $sNewState);
@@ -4542,67 +4575,71 @@ abstract class DBObject implements iDisplay
// array('target_state'=>..., 'actions'=>array of handlers procs, 'user_restriction'=>TBD // array('target_state'=>..., 'actions'=>array of handlers procs, 'user_restriction'=>TBD
$bSuccess = true; $bSuccess = true;
$sActionDesc = ''; // Prevent current object from being updated by the actions
foreach ($aTransitionDef['actions'] as $actionHandler) $this->AddCurrentObjectInCrudStack('APPLY_STIMULUS');
{ $bIsNewlyProtected = MetaModel::StartReentranceProtection($this);
if (is_string($actionHandler)) try {
{ foreach ($aTransitionDef['actions'] as $actionHandler) {
// Old (pre-2.1.0 modules) action definition without any parameter if (is_string($actionHandler)) {
$aActionCallSpec = array($this, $actionHandler); // Old (pre-2.1.0 modules) action definition without any parameter
$sActionDesc = $sClass.'::'.$actionHandler; $aActionCallSpec = array($this, $actionHandler);
$sActionDesc = $sClass.'::'.$actionHandler;
if (!is_callable($aActionCallSpec)) if (!is_callable($aActionCallSpec)) {
{ throw new CoreException("Unable to call action: $sClass::$actionHandler");
throw new CoreException("Unable to call action: $sClass::$actionHandler");
}
$bRet = call_user_func($aActionCallSpec, $sStimulusCode);
}
else // if (is_array($actionHandler))
{
// New syntax: 'verb' and typed parameters
$sAction = $actionHandler['verb'];
$sActionDesc = "$sClass::$sAction";
$aParams = array();
foreach($actionHandler['params'] as $aDefinition)
{
$sParamType = array_key_exists('type', $aDefinition) ? $aDefinition['type'] : 'string';
switch($sParamType)
{
case 'int':
$value = (int)$aDefinition['value'];
break;
case 'float':
$value = (float)$aDefinition['value'];
break;
case 'bool':
$value = (bool)$aDefinition['value'];
break;
case 'reference':
$value = ${$aDefinition['value']};
break;
case 'string':
default:
$value = (string)$aDefinition['value'];
} }
$aParams[] = $value; $bRet = call_user_func($aActionCallSpec, $sStimulusCode);
} else // if (is_array($actionHandler))
{
// New syntax: 'verb' and typed parameters
$sAction = $actionHandler['verb'];
$sActionDesc = "$sClass::$sAction";
$aParams = array();
foreach ($actionHandler['params'] as $aDefinition) {
$sParamType = array_key_exists('type', $aDefinition) ? $aDefinition['type'] : 'string';
switch ($sParamType) {
case 'int':
$value = (int)$aDefinition['value'];
break;
case 'float':
$value = (float)$aDefinition['value'];
break;
case 'bool':
$value = (bool)$aDefinition['value'];
break;
case 'reference':
$value = ${$aDefinition['value']};
break;
case 'string':
default:
$value = (string)$aDefinition['value'];
}
$aParams[] = $value;
}
$aCallSpec = array($this, $sAction);
$bRet = call_user_func_array($aCallSpec, $aParams);
}
// if one call fails, the whole is considered as failed
// (in case there is no returned value, null is obtained and means "ok")
if ($bRet === false) {
IssueLog::Info("Lifecycle action $sActionDesc returned false on object #$sClass:".$this->GetKey());
$bSuccess = false;
} }
$aCallSpec = array($this, $sAction);
$bRet = call_user_func_array($aCallSpec, $aParams);
} }
// if one call fails, the whole is considered as failed } finally {
// (in case there is no returned value, null is obtained and means "ok") if ($bIsNewlyProtected) {
if ($bRet === false) // Stops protection only if the object was not already protected
{ MetaModel::StopReentranceProtection($this);
IssueLog::Info("Lifecycle action $sActionDesc returned false on object #$sClass:".$this->GetKey());
$bSuccess = false;
} }
$this->RemoveCurrentObjectInCrudStack();
} }
if ($bSuccess) if ($bSuccess)
{ {
$this->sStimulusBeingApplied = $sStimulusCode;
// Stop watches // Stop watches
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
{ {
@@ -4631,6 +4668,7 @@ abstract class DBObject implements iDisplay
$this->m_aCurrValues[$sAttCode] = $aBackupValues[$sAttCode]; $this->m_aCurrValues[$sAttCode] = $aBackupValues[$sAttCode];
} }
} }
$this->LogCRUDExit(__METHOD__, 'Current State: '.$this->Get($sStateAttCode));
return $bSuccess; return $bSuccess;
} }
@@ -6617,7 +6655,7 @@ abstract class DBObject implements iDisplay
* @return void * @return void
* @since 3.1.0 * @since 3.1.0
*/ */
protected function FireEventCheckToWrite(): void protected function FireEventCheckToWrite(?string $sStimulusBeingApplied): void
{ {
} }
@@ -6625,7 +6663,7 @@ abstract class DBObject implements iDisplay
* @return void * @return void
* @since 3.1.0 * @since 3.1.0
*/ */
protected function FireEventBeforeWrite() protected function FireEventBeforeWrite(?string $sStimulusBeingApplied)
{ {
} }
@@ -6635,7 +6673,7 @@ abstract class DBObject implements iDisplay
* @return void * @return void
* @since 3.1.0 * @since 3.1.0
*/ */
protected function FireEventAfterWrite(array $aChanges, bool $bIsNew): void protected function FireEventAfterWrite(array $aChanges, bool $bIsNew, ?string $sStimulusBeingApplied): void
{ {
} }
@@ -6673,7 +6711,7 @@ abstract class DBObject implements iDisplay
* @return void * @return void
* @since 3.1.0 * @since 3.1.0
*/ */
protected function FireEventComputeValues(): void protected function FireEventComputeValues(?string $sStimulusBeingApplied): void
{ {
} }
@@ -6715,12 +6753,13 @@ abstract class DBObject implements iDisplay
$oRootClass = MetaModel::GetRootClass($sClass); $oRootClass = MetaModel::GetRootClass($sClass);
foreach (self::$m_aCrudStack as $aCrudStackEntry) { foreach (self::$m_aCrudStack as $aCrudStackEntry) {
if (($oRootClass === $aCrudStackEntry['class']) if (($oRootClass === $aCrudStackEntry['class']) && ($sConvertedId === $aCrudStackEntry['id'])) {
&& ($sConvertedId === $aCrudStackEntry['id'])) { IssueLog::Trace('CRUD '.__METHOD__." $sClass:$sId IS in CRUD Stack", LogChannels::DM_CRUD);
return true; return true;
} }
} }
IssueLog::Trace('CRUD '.__METHOD__." $sClass:$sId NOT in CRUD Stack", LogChannels::DM_CRUD);
return false; return false;
} }
@@ -6738,10 +6777,12 @@ abstract class DBObject implements iDisplay
$sRootClass = MetaModel::GetRootClass($sClass); $sRootClass = MetaModel::GetRootClass($sClass);
foreach (self::$m_aCrudStack as $aCrudStackEntry) { foreach (self::$m_aCrudStack as $aCrudStackEntry) {
if ($sRootClass === $aCrudStackEntry['class']) { if ($sRootClass === $aCrudStackEntry['class']) {
IssueLog::Trace("CRUD ".__METHOD__." $sClass IS in CRUD Stack", LogChannels::DM_CRUD);
return true; return true;
} }
} }
IssueLog::Trace('CRUD '.__METHOD__." $sClass NOT in CRUD Stack", LogChannels::DM_CRUD);
return false; return false;
} }
@@ -6751,17 +6792,20 @@ abstract class DBObject implements iDisplay
* @param string $sCrudType * @param string $sCrudType
* *
* @return void * @return void
* @throws \CoreException
* @since 3.1.0 N°5609 * @since 3.1.0 N°5609
*/ */
private function AddCurrentObjectInCrudStack(string $sCrudType): void private function AddCurrentObjectInCrudStack(string $sCrudType): void
{ {
$this->LogCRUDDebug(__METHOD__);
$sRootClass = MetaModel::GetRootClass(get_class($this)); $sRootClass = MetaModel::GetRootClass(get_class($this));
$sKey = (string)$this->GetKey();
self::$m_aCrudStack[] = [ self::$m_aCrudStack[] = [
'type' => $sCrudType, 'type' => $sCrudType,
'class' => $sRootClass, 'class' => $sRootClass,
'id' => (string)$this->GetKey(), // GetKey() doesn't have type hinting, so forcing type to avoid getting an int 'id' => $sKey, // GetKey() doesn't have type hinting, so forcing type to avoid getting an int
]; ];
$iCount = count(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, "$sCrudType $sRootClass:$sKey count $iCount");
} }
/** /**
@@ -6773,10 +6817,15 @@ abstract class DBObject implements iDisplay
*/ */
private function UpdateCurrentObjectInCrudStack(): void private function UpdateCurrentObjectInCrudStack(): void
{ {
$this->LogCRUDDebug(__METHOD__);
$aCurrentCrudStack = array_pop(self::$m_aCrudStack); $aCurrentCrudStack = array_pop(self::$m_aCrudStack);
$aCurrentCrudStack['id'] = (string)$this->GetKey(); $sOldId = $aCurrentCrudStack['id'];
$sNewId = (string)$this->GetKey();
$aCurrentCrudStack['id'] = $sNewId;
self::$m_aCrudStack[] = $aCurrentCrudStack; self::$m_aCrudStack[] = $aCurrentCrudStack;
$sClass = $aCurrentCrudStack['class'];
$sType = $aCurrentCrudStack['type'];
$iCount = count(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, "$sType $sClass:$sOldId => $sClass:$sNewId count $iCount");
} }
/** /**
@@ -6788,7 +6837,11 @@ abstract class DBObject implements iDisplay
private function RemoveCurrentObjectInCrudStack(): void private function RemoveCurrentObjectInCrudStack(): void
{ {
$aRemoved = array_pop(self::$m_aCrudStack); $aRemoved = array_pop(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, $aRemoved['class'].':'.$aRemoved['id']); $sType = $aRemoved['type'];
$sClass = $aRemoved['class'];
$sId = $aRemoved['id'];
$iCount = count(self::$m_aCrudStack);
$this->LogCRUDDebug(__METHOD__, "$sType $sClass:$sId count $iCount");
} }
/** /**
@@ -6805,37 +6858,53 @@ abstract class DBObject implements iDisplay
protected function LogCRUDEnter($sFunction, $sComment = '') protected function LogCRUDEnter($sFunction, $sComment = '')
{ {
$sClass = get_class($this); $sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey(); $sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '-'); $sPadding = str_pad('', count(self::$m_aCrudStack), '-');
IssueLog::Debug("CRUD +$sPadding> $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD); IssueLog::Debug("CRUD +$sPadding> $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
} }
protected function LogCRUDExit($sFunction, $sComment = '') protected function LogCRUDExit($sFunction, $sComment = '')
{ {
$sClass = get_class($this); $sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey(); $sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '-'); $sPadding = str_pad('', count(self::$m_aCrudStack), '-');
if (strlen($sComment) === 0) { if (strlen($sComment) === 0) {
IssueLog::Trace("CRUD <$sPadding+ $sFunction $sClass:$sKey", LogChannels::DM_CRUD); IssueLog::Trace("CRUD <$sPadding+ $sFunction $sClass:$sKey", LogChannels::DM_CRUD);
} else { } else {
IssueLog::Debug("CRUD <$sPadding+ $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD); IssueLog::Debug("CRUD <$sPadding+ $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
} }
} }
protected function LogCRUDDebug($sFunction, $sComment = '') protected function LogCRUDDebug($sFunction, $sComment = '')
{ {
$sClass = get_class($this); $sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey(); $sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '-'); $sPadding = str_pad('', count(self::$m_aCrudStack), '-');
IssueLog::Debug("CRUD --$sPadding $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD); IssueLog::Debug("CRUD --$sPadding $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
} }
protected function LogCRUDError($sFunction, $sComment = '') protected function LogCRUDError($sFunction, $sComment = '')
{ {
$sClass = get_class($this); $sClass = get_class($this);
if (utils::StartsWith($sClass, 'CMDBChange')) {
return;
}
$sKey = $this->GetKey(); $sKey = $this->GetKey();
$sUUID = $this->m_sObjectUniqId;
$sPadding = str_pad('', count(self::$m_aCrudStack), '!'); $sPadding = str_pad('', count(self::$m_aCrudStack), '!');
IssueLog::Error("CRUD !!$sPadding Error $sFunction $sClass:$sKey $sComment", LogChannels::DM_CRUD); IssueLog::Error("CRUD !!$sPadding Error $sFunction $sClass:$sKey ($sUUID) $sComment", LogChannels::DM_CRUD);
} }
/** /**
@@ -6925,5 +6994,28 @@ abstract class DBObject implements iDisplay
{ {
return array_key_exists($sSection, $this->aContext); return array_key_exists($sSection, $this->aContext);
} }
/**
* @param string $sAttCode
*
* @return void
* @throws CoreException
* @throws OQLException
* @throws Exception
*/
private function UpdateDependentComputedAttributes(string $sAttCode): void
{
foreach (MetaModel::GetDependentAttributes(get_class($this), $sAttCode) as $sCode) {
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sCode);
if ($oAttDef->IsComputed()) {
$oExpression = Expression::FromOQL($oAttDef->GetParams()['expression']);
$value = $this->EvaluateExpression($oExpression);
$aAllowedValues = $oAttDef->GetAllowedValues();
if(is_null($aAllowedValues) || in_array($value, $aAllowedValues)) {
$this->_Set($sCode, $oAttDef->MakeRealValue($value, $this));
} ;
}
}
}
} }

View File

@@ -51,7 +51,7 @@ class DBProperty extends DBObject
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("value", array("allowed_values"=>null, "sql"=>"value", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("change_date", array("allowed_values"=>null, "sql"=>"change_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("change_date", array("allowed_values"=>null, "sql"=>"change_date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("change_comment", array("allowed_values"=>null, "sql"=>"change_comment", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("change_comment", array("allowed_values"=>null, "sql"=>"change_comment", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
} }

View File

@@ -1552,13 +1552,13 @@ abstract class DBSearch
} }
$sLogFile = 'queries.latest'; $sLogFile = 'queries.latest';
file_put_contents(APPROOT.'data/'.$sLogFile.'.html', $sHtml); file_put_contents(utils::GetDataPath().$sLogFile.'.html', $sHtml);
$sLog = "<?php\n\$aQueriesLog = ".var_export(self::$m_aQueriesLog, true).";"; $sLog = "<?php\n\$aQueriesLog = ".var_export(self::$m_aQueriesLog, true).";";
file_put_contents(APPROOT.'data/'.$sLogFile.'.log', $sLog); file_put_contents(utils::GetDataPath().$sLogFile.'.log', $sLog);
// Cumulate the queries // Cumulate the queries
$sAllQueries = APPROOT.'data/queries.log'; $sAllQueries = utils::GetDataPath().'queries.log';
if (file_exists($sAllQueries)) if (file_exists($sAllQueries))
{ {
// Merge the new queries into the existing log // Merge the new queries into the existing log

View File

@@ -154,7 +154,7 @@ class EMail implements iEMail
*/ */
public function SetInReplyTo(string $sMessageId) public function SetInReplyTo(string $sMessageId)
{ {
$this->AddToHeader('In-Reply-To', $sMessageId); $this->oMailer->SetInReplyTo($sMessageId);
} }
public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null) public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null)

View File

@@ -39,7 +39,7 @@ class Event extends DBObject implements iDisplay
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes(); //MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); // MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
@@ -131,7 +131,7 @@ class EventNotification extends Event
"db_finalclass_field" => "", "db_finalclass_field" => "",
"order_by_default" => array('date' => false), "order_by_default" => array('date' => false),
'indexes' => array( 'indexes' => array(
array('object_id'), array( 'object_class', 'object_id'),
) )
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
@@ -139,9 +139,11 @@ class EventNotification extends Event
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> "", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> "", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass" => "Action", "jointype" => "", "allowed_values" => null, "sql" => "action_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass" => "Action", "jointype" => "", "allowed_values" => null, "sql" => "action_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values" => null, "sql" => "object_id", "default_value" => 0, "is_null_allowed" => false, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values" => null, "sql" => "object_id", "default_value" => 0, "is_null_allowed" => false, "depends_on" => array())));
//@since 3.2.0
MetaModel::Init_AddAttribute(new AttributeClass("object_class", array("class_category"=>"", "more_values"=>"", "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>true /*to avoid setting AbstractResource as default in database*/, "depends_on"=>array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_id')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_class', 'object_id')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'message')); // Attributes to be displayed for a list MetaModel::Init_SetZListItems('list', array('date', 'message')); // Attributes to be displayed for a list
// Search criteria // Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form // MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
@@ -176,7 +178,7 @@ class EventNotificationEmail extends EventNotification
MetaModel::Init_AddAttribute(new AttributeTable("attachments", array("allowed_values"=>null, "sql"=>"attachments", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeTable("attachments", array("allowed_values"=>null, "sql"=>"attachments", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists // Display lists
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body', 'attachments')); // Attributes to be displayed for the complete details MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_class', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body', 'attachments')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'message', 'to', 'subject', 'attachments')); // Attributes to be displayed for a list MetaModel::Init_SetZListItems('list', array('date', 'message', 'to', 'subject', 'attachments')); // Attributes to be displayed for a list
// Search criteria // Search criteria

View File

@@ -278,7 +278,7 @@ class HTMLDOMSanitizer extends DOMSanitizer
protected static $aTagsWhiteList = array( protected static $aTagsWhiteList = array(
'html' => array(), 'html' => array(),
'body' => array(), 'body' => array(),
'a' => array('href', 'name', 'style', 'class', 'target', 'title', 'data-role', 'data-object-class', 'data-object-id'), 'a' => array('href', 'name', 'style', 'class', 'target', 'title', 'data-role', 'data-object-class', 'data-object-id', 'data-object-key'),
'p' => array('style', 'class'), 'p' => array('style', 'class'),
'blockquote' => array('style', 'class'), 'blockquote' => array('style', 'class'),
'br' => array(), 'br' => array(),
@@ -354,6 +354,8 @@ class HTMLDOMSanitizer extends DOMSanitizer
'font-style', 'font-style',
'height', 'height',
'margin', 'margin',
'margin-left',
'margin-right',
'padding', 'padding',
'text-align', 'text-align',
'vertical-align', 'vertical-align',

View File

@@ -54,7 +54,7 @@ class InlineImage extends DBObject
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes(); MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("expire", array("allowed_values"=>null, "sql"=>'expire', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false))); MetaModel::Init_AddAttribute(new AttributeDateTime("expire", array("allowed_values" => null, "sql" => 'expire', "default_value" => 'DATE_ADD(NOW(), INTERVAL 1 DAY)', "is_null_allowed" => false, "depends_on" => array(), "always_load_in_tables" => false)));
MetaModel::Init_AddAttribute(new AttributeString("temp_id", array("allowed_values"=>null, "sql"=>'temp_id', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false))); MetaModel::Init_AddAttribute(new AttributeString("temp_id", array("allowed_values"=>null, "sql"=>'temp_id', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeString("item_class", array("allowed_values"=>null, "sql"=>'item_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false))); MetaModel::Init_AddAttribute(new AttributeString("item_class", array("allowed_values"=>null, "sql"=>'item_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeObjectKey("item_id", array("class_attcode"=>'item_class', "allowed_values"=>null, "sql"=>'item_id', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false))); MetaModel::Init_AddAttribute(new AttributeObjectKey("item_id", array("class_attcode"=>'item_class', "allowed_values"=>null, "sql"=>'item_id', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
@@ -541,80 +541,6 @@ JS
CombodoCKEditorHandler.EnableImageUpload('#' + $(this).attr('id'), '$sAbsoluteUrlAppRoot'+'pages/ajax.render.php?operation=cke_img_upload&temp_id=$sTempId&obj_class=$sObjClass&obj_key=$iObjKey'); CombodoCKEditorHandler.EnableImageUpload('#' + $(this).attr('id'), '$sAbsoluteUrlAppRoot'+'pages/ajax.render.php?operation=cke_img_upload&temp_id=$sTempId&obj_class=$sObjClass&obj_key=$iObjKey');
}); });
JS; JS;
return
<<<JS
// Hook the file upload of all CKEditor instances
$('.htmlEditor').each(function() {
var oEditor = $(this).ckeditorGet();
oEditor.config.filebrowserBrowseUrl = '$sAbsoluteUrlAppRoot'+'pages/ajax.render.php?operation=cke_browse&temp_id=$sTempId&obj_class=$sObjClass&obj_key=$iObjKey';
oEditor.on( 'fileUploadResponse', function( evt ) {
var fileLoader = evt.data.fileLoader;
var xhr = fileLoader.xhr;
var data = evt.data;
try {
var response = JSON.parse( xhr.responseText );
// Error message does not need to mean that upload finished unsuccessfully.
// It could mean that ex. file name was changes during upload due to naming collision.
if ( response.error && response.error.message ) {
data.message = response.error.message;
}
// But !uploaded means error.
if ( !response.uploaded ) {
evt.cancel();
} else {
data.fileName = response.fileName;
data.url = response.url;
// Do not call the default listener.
evt.stop();
}
} catch ( err ) {
// Response parsing error.
data.message = fileLoader.lang.filetools.responseError;
window.console && window.console.log( xhr.responseText );
evt.cancel();
}
} );
oEditor.on( 'fileUploadRequest', function( evt ) {
evt.data.fileLoader.uploadUrl += '?operation=cke_img_upload&temp_id=$sTempId&obj_class=$sObjClass';
}, null, null, 4 ); // Listener with priority 4 will be executed before priority 5.
oEditor.on( 'instanceReady', function() {
if(!CKEDITOR.env.iOS && $('#'+oEditor.id+'_toolbox .ibo-vendors-ckeditor--toolbar-fullscreen-button').length == 0)
{
$('#'+oEditor.id+'_toolbox').append('<span class="ibo-vendors-ckeditor--toolbar-fullscreen-button editor-fullscreen-button" data-role="ibo-vendors-ckeditor--toolbar-fullscreen-button" title="$sToggleFullScreen">&nbsp;</span>');
$('#'+oEditor.id+'_toolbox .ibo-vendors-ckeditor--toolbar-fullscreen-button').on('click', function() {
oEditor.execCommand('maximize');
if ($(this).closest('.cke_maximized').length != 0)
{
$('#'+oEditor.id+'_toolbar_collapser').trigger('click');
}
});
}
if (oEditor.widgets.registered.uploadimage)
{
oEditor.widgets.registered.uploadimage.onUploaded = function( upload ) {
var oData = JSON.parse(upload.xhr.responseText);
this.replaceWith( '<img src="' + upload.url + '" ' +
'width="' + oData.width + '" ' +
'height="' + oData.height + '">' );
}
}
});
});
JS
;
}
public static function EnableCKEditor5ImageUpload(DBObject $oObject, $sTempId){
return <<<JS
// Hook the file upload of all CKEditor instances
JS;
} }

View File

@@ -2661,7 +2661,7 @@ abstract class MetaModel
*/ */
public static function GetAttributeFlags($sClass, $sState, $sAttCode) public static function GetAttributeFlags($sClass, $sState, $sAttCode)
{ {
$iFlags = 0; // By default (if no life cycle) no flag at all $iFlags = 0;
if (self::HasLifecycle($sClass)) { if (self::HasLifecycle($sClass)) {
$aStates = MetaModel::EnumStates($sClass); $aStates = MetaModel::EnumStates($sClass);
if (!array_key_exists($sState, $aStates)) { if (!array_key_exists($sState, $aStates)) {
@@ -7112,7 +7112,7 @@ abstract class MetaModel
if ($iKey < 0) { if ($iKey < 0) {
return "$sTargetClass: $iKey (invalid value)"; return "$sTargetClass: $iKey (invalid value)";
} }
$oObj = self::GetObject($sTargetClass, $iKey, false); $oObj = self::GetObject($sTargetClass, $iKey, false);
if (is_null($oObj)) { if (is_null($oObj)) {
// Whatever we are looking for, the root class is the key to search for // Whatever we are looking for, the root class is the key to search for
$sRootClass = self::GetRootClass($sTargetClass); $sRootClass = self::GetRootClass($sTargetClass);
@@ -7532,8 +7532,41 @@ abstract class MetaModel
return $aEntries; return $aEntries;
} }
public static function ResetAllCaches($sEnvironment = null)
{
if (is_null($sEnvironment)) {
$sEnvironment = MetaModel::GetEnvironment();
}
$sEnvironmentId = md5(APPROOT).'-'.$sEnvironment;
$sAppIdentity = 'itop-'.$sEnvironmentId;
require_once(APPROOT.'/core/dict.class.inc.php');
Dict::ResetCache($sAppIdentity);
if (function_exists('apc_delete')) {
foreach (self::GetCacheEntries($sEnvironmentId) as $sKey => $aAPCInfo) {
$sAPCKey = $aAPCInfo['info'];
apc_delete($sAPCKey);
}
}
require_once(APPROOT.'core/userrights.class.inc.php');
UserRights::FlushPrivileges();
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset')) {
// Zend opcode cache
opcache_reset();
}
require_once(APPROOT.'setup/setuputils.class.inc.php');
SetupUtils::rrmdir(utils::GetCachePath($sEnvironment));
}
/** /**
* @internal
* @param string $sEnvironmentId * @param string $sEnvironmentId
* @deprecated 3.2.1
*/ */
public static function ResetCache($sEnvironmentId = null) public static function ResetCache($sEnvironmentId = null)
{ {
@@ -7557,6 +7590,13 @@ abstract class MetaModel
require_once(APPROOT.'core/userrights.class.inc.php'); require_once(APPROOT.'core/userrights.class.inc.php');
UserRights::FlushPrivileges(); UserRights::FlushPrivileges();
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset'))
{
// Zend opcode cache
opcache_reset();
}
} }
/** /**

View File

@@ -182,14 +182,14 @@ class PHP_LexerGenerator_Lexer
$this->token = self::COMMENTEND; $this->token = self::COMMENTEND;
return true; return true;
} }
if (preg_match('/\G%([a-z]+)/', $this->data, $token, null, $this->N)) { if (preg_match('/\G%([a-z]+)/', $this->data, $token, 0, $this->N)) {
$this->value = $token[1]; $this->value = $token[1];
$this->N += strlen($token[1]) + 1; $this->N += strlen($token[1]) + 1;
$this->state = 'DeclarePI'; $this->state = 'DeclarePI';
$this->token = self::PI; $this->token = self::PI;
return true; return true;
} }
if (preg_match('/\G[a-zA-Z_][a-zA-Z0-9_]*/', $this->data, $token, null, $this->N)) { if (preg_match('/\G[a-zA-Z_][a-zA-Z0-9_]*/', $this->data, $token, 0, $this->N)) {
$this->value = $token[0]; $this->value = $token[0];
$this->token = self::PATTERN; $this->token = self::PATTERN;
$this->N += strlen($token[0]); $this->N += strlen($token[0]);
@@ -216,7 +216,7 @@ class PHP_LexerGenerator_Lexer
if ($this->data[$this->N] == '{') { if ($this->data[$this->N] == '{') {
return $this->lexCode(); return $this->lexCode();
} }
if (!preg_match("/\G[^\n]+/", $this->data, $token, null, $this->N)) { if (!preg_match("/\G[^\n]+/", $this->data, $token, 0, $this->N)) {
$this->error('Unexpected end of file'); $this->error('Unexpected end of file');
return false; return false;
} }
@@ -242,7 +242,7 @@ class PHP_LexerGenerator_Lexer
if ($this->data[$this->N] == '{') { if ($this->data[$this->N] == '{') {
return $this->lexCode(); return $this->lexCode();
} }
if (!preg_match("/\G[^\n]+/", $this->data, $token, null, $this->N)) { if (!preg_match("/\G[^\n]+/", $this->data, $token, 0, $this->N)) {
$this->error('Unexpected end of file'); $this->error('Unexpected end of file');
return false; return false;
} }
@@ -406,7 +406,7 @@ class PHP_LexerGenerator_Lexer
if ($this->data[$this->N] == '\'') { if ($this->data[$this->N] == '\'') {
return $this->lexQuote('\''); return $this->lexQuote('\'');
} }
if (preg_match('/\G%([a-zA-Z_]+)/', $this->data, $token, null, $this->N)) { if (preg_match('/\G%([a-zA-Z_]+)/', $this->data, $token, 0, $this->N)) {
$this->value = $token[1]; $this->value = $token[1];
$this->N += strlen($token[1]) + 1; $this->N += strlen($token[1]) + 1;
$this->state = 'DeclarePIRule'; $this->state = 'DeclarePIRule';
@@ -419,7 +419,7 @@ class PHP_LexerGenerator_Lexer
if ($this->data[$this->N] == '"') { if ($this->data[$this->N] == '"') {
return $this->lexQuote(); return $this->lexQuote();
} }
if (preg_match('/\G[a-zA-Z_][a-zA-Z0-9_]*/', $this->data, $token, null, $this->N)) { if (preg_match('/\G[a-zA-Z_][a-zA-Z0-9_]*/', $this->data, $token, 0, $this->N)) {
$this->value = $token[0]; $this->value = $token[0];
$this->N += strlen($token[0]); $this->N += strlen($token[0]);
$this->token = self::SUBPATTERN; $this->token = self::SUBPATTERN;

View File

@@ -33,17 +33,19 @@ class PHP_LexerGenerator_ParseryyToken implements ArrayAccess
return $this->_string; return $this->_string;
} }
function offsetExists($offset) function offsetExists($offset): bool
{ {
return isset($this->metadata[$offset]); return isset($this->metadata[$offset]);
} }
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
#[\ReturnTypeWillChange]
function offsetGet($offset) function offsetGet($offset)
{ {
return $this->metadata[$offset]; return $this->metadata[$offset];
} }
function offsetSet($offset, $value) function offsetSet($offset, $value): void
{ {
if ($offset === null) { if ($offset === null) {
if (isset($value[0])) { if (isset($value[0])) {
@@ -66,7 +68,7 @@ class PHP_LexerGenerator_ParseryyToken implements ArrayAccess
} }
} }
function offsetUnset($offset) function offsetUnset($offset): void
{ {
unset($this->metadata[$offset]); unset($this->metadata[$offset]);
} }
@@ -278,7 +280,7 @@ class PHP_LexerGenerator_Parser#line 171 "Parser.php"
$match = false; $match = false;
foreach ($yy_yymore_patterns[' . $this->token . '] as $index => $rule) { foreach ($yy_yymore_patterns[' . $this->token . '] as $index => $rule) {
if (preg_match(\'/\' . $rule . \'/' . $this->patternFlags . '\', if (preg_match(\'/\' . $rule . \'/' . $this->patternFlags . '\',
' . $this->input . ', $yymatches, null, ' . $this->counter . ')) { ' . $this->input . ', $yymatches, 0, ' . $this->counter . ')) {
$yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
if ($match) { if ($match) {
if (strlen($yymatches[0]) > strlen($match[0][0])) { if (strlen($yymatches[0]) > strlen($match[0][0])) {
@@ -350,7 +352,7 @@ class PHP_LexerGenerator_Parser#line 171 "Parser.php"
$pattern . '\';' . "\n"); $pattern . '\';' . "\n");
fwrite($this->out, ' fwrite($this->out, '
do { do {
if (preg_match($yy_global_pattern,' . $this->input . ', $yymatches, null, ' . if (preg_match($yy_global_pattern,' . $this->input . ', $yymatches, 0, ' .
$this->counter . $this->counter .
')) { ')) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
@@ -408,7 +410,7 @@ class PHP_LexerGenerator_Parser#line 171 "Parser.php"
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match(\'/\' . $yy_yymore_patterns[' . $this->token . '][1] . \'/' . $this->patternFlags . '\', if (preg_match(\'/\' . $yy_yymore_patterns[' . $this->token . '][1] . \'/' . $this->patternFlags . '\',
' . $this->input . ', $yymatches, null, ' . $this->counter .')) { ' . $this->input . ', $yymatches, 0, ' . $this->counter .')) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match

View File

@@ -187,7 +187,7 @@ require_once 'PHP/LexerGenerator/Exception.php';
$match = false; $match = false;
foreach ($yy_yymore_patterns[' . $this->token . '] as $index => $rule) { foreach ($yy_yymore_patterns[' . $this->token . '] as $index => $rule) {
if (preg_match(\'/\' . $rule . \'/' . $this->patternFlags . '\', if (preg_match(\'/\' . $rule . \'/' . $this->patternFlags . '\',
' . $this->input . ', $yymatches, null, ' . $this->counter . ')) { ' . $this->input . ', $yymatches, 0, ' . $this->counter . ')) {
$yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
if ($match) { if ($match) {
if (strlen($yymatches[0]) > strlen($match[0][0])) { if (strlen($yymatches[0]) > strlen($match[0][0])) {
@@ -259,7 +259,7 @@ require_once 'PHP/LexerGenerator/Exception.php';
$pattern . '\';' . "\n"); $pattern . '\';' . "\n");
fwrite($this->out, ' fwrite($this->out, '
do { do {
if (preg_match($yy_global_pattern,' . $this->input . ', $yymatches, null, ' . if (preg_match($yy_global_pattern,' . $this->input . ', $yymatches, 0, ' .
$this->counter . $this->counter .
')) { ')) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
@@ -317,7 +317,7 @@ require_once 'PHP/LexerGenerator/Exception.php';
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match(\'/\' . $yy_yymore_patterns[' . $this->token . '][1] . \'/' . $this->patternFlags . '\', if (preg_match(\'/\' . $yy_yymore_patterns[' . $this->token . '][1] . \'/' . $this->patternFlags . '\',
' . $this->input . ', $yymatches, null, ' . $this->counter .')) { ' . $this->input . ', $yymatches, 0, ' . $this->counter .')) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns $yymatches = array_filter($yymatches, \'strlen\'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match

View File

@@ -110,7 +110,7 @@ class PHP_LexerGenerator_Regex_Lexer
$yy_global_pattern = '/\G(\\\\\\\\)|\G([^[\\\\^$.|()?*+{}]+)|\G(\\\\[][{}*.^$|?()+])|\G(\\[)|\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)/'; $yy_global_pattern = '/\G(\\\\\\\\)|\G([^[\\\\^$.|()?*+{}]+)|\G(\\\\[][{}*.^$|?()+])|\G(\\[)|\G(\\|)|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[0-9][0-9])|\G(\\\\[abBGcedDsSwW0C]|\\\\c\\\\)|\G(\\^)|\G(\\\\A)|\G(\\))|\G(\\$)|\G(\\*\\?|\\+\\?|[*?+]|\\{[0-9]+\\}|\\{[0-9]+,\\}|\\{[0-9]+,[0-9]+\\})|\G(\\\\[zZ])|\G(\\(\\?)|\G(\\()|\G(\\.)|\G(\\\\[1-9])|\G(\\\\p\\{\\^?..?\\}|\\\\P\\{..?\\}|\\\\X)|\G(\\\\p\\{C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p\\{\\^C[cfnos]?|L[lmotu]?|M[cen]?|N[dlo]?|P[cdefios]?|S[ckmo]?|Z[lps]?\\})|\G(\\\\p[CLMNPSZ])|\G(\\\\)/';
do { do {
if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) { if (preg_match($yy_global_pattern,$this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) { if (!count($yymatches)) {
@@ -180,7 +180,7 @@ class PHP_LexerGenerator_Regex_Lexer
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/', if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
$this->input, $yymatches, null, $this->N)) { $this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match
@@ -360,7 +360,7 @@ class PHP_LexerGenerator_Regex_Lexer
$yy_global_pattern = '/\G(\\^)|\G(\\])|\G(.)/'; $yy_global_pattern = '/\G(\\^)|\G(\\])|\G(.)/';
do { do {
if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) { if (preg_match($yy_global_pattern,$this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) { if (!count($yymatches)) {
@@ -410,7 +410,7 @@ class PHP_LexerGenerator_Regex_Lexer
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/', if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
$this->input, $yymatches, null, $this->N)) { $this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match
@@ -497,7 +497,7 @@ class PHP_LexerGenerator_Regex_Lexer
$yy_global_pattern = '/\G(\\\\\\\\)|\G(\\])|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)/'; $yy_global_pattern = '/\G(\\\\\\\\)|\G(\\])|\G(\\\\[frnt]|\\\\x[0-9a-fA-F][0-9a-fA-F]?|\\\\[0-7][0-7][0-7]|\\\\x\\{[0-9a-fA-F]+\\})|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G(\\\\[]\.\-\^])|\G(-(?!]))|\G([^\-\\\\])|\G(\\\\)|\G(.)/';
do { do {
if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) { if (preg_match($yy_global_pattern,$this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) { if (!count($yymatches)) {
@@ -555,7 +555,7 @@ class PHP_LexerGenerator_Regex_Lexer
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/', if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
$this->input, $yymatches, null, $this->N)) { $this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match
@@ -678,7 +678,7 @@ class PHP_LexerGenerator_Regex_Lexer
$yy_global_pattern = '/\G(\\\\\\\\)|\G(\\\\\\])|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)/'; $yy_global_pattern = '/\G(\\\\\\\\)|\G(\\\\\\])|\G(\\\\[bacedDsSwW0C]|\\\\c\\\\|\\\\x\\{[0-9a-fA-F]+\\}|\\\\[0-7][0-7][0-7]|\\\\x[0-9a-fA-F][0-9a-fA-F]?)|\G(\\\\[0-9][0-9])|\G(\\\\[1-9])|\G([^\-\\\\])|\G(\\\\)/';
do { do {
if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) { if (preg_match($yy_global_pattern,$this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) { if (!count($yymatches)) {
@@ -732,7 +732,7 @@ class PHP_LexerGenerator_Regex_Lexer
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/', if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
$this->input, $yymatches, null, $this->N)) { $this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match
@@ -842,7 +842,7 @@ class PHP_LexerGenerator_Regex_Lexer
$yy_global_pattern = '/\G([imsxUX]+-[imsxUX]+|[imsxUX]+|-[imsxUX]+)|\G(:)|\G(\\))|\G(P<[^>]+>)|\G(<=)|\G(<!)|\G(=)|\G(!)|\G(>)|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)/'; $yy_global_pattern = '/\G([imsxUX]+-[imsxUX]+|[imsxUX]+|-[imsxUX]+)|\G(:)|\G(\\))|\G(P<[^>]+>)|\G(<=)|\G(<!)|\G(=)|\G(!)|\G(>)|\G(\\(\\?)|\G(#[^)]+)|\G(R)|\G(.)/';
do { do {
if (preg_match($yy_global_pattern,$this->input, $yymatches, null, $this->N)) { if (preg_match($yy_global_pattern,$this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) { if (!count($yymatches)) {
@@ -902,7 +902,7 @@ class PHP_LexerGenerator_Regex_Lexer
} }
$yysubmatches = array(); $yysubmatches = array();
if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/', if (preg_match('/' . $yy_yymore_patterns[$this->token][1] . '/',
$this->input, $yymatches, null, $this->N)) { $this->input, $yymatches, 0, $this->N)) {
$yysubmatches = $yymatches; $yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
next($yymatches); // skip global match next($yymatches); // skip global match

View File

@@ -33,17 +33,19 @@ class PHP_LexerGenerator_Regex_yyToken implements ArrayAccess
return $this->_string; return $this->_string;
} }
function offsetExists($offset) function offsetExists($offset): bool
{ {
return isset($this->metadata[$offset]); return isset($this->metadata[$offset]);
} }
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
#[\ReturnTypeWillChange]
function offsetGet($offset) function offsetGet($offset)
{ {
return $this->metadata[$offset]; return $this->metadata[$offset];
} }
function offsetSet($offset, $value) function offsetSet($offset, $value): void
{ {
if ($offset === null) { if ($offset === null) {
if (isset($value[0])) { if (isset($value[0])) {
@@ -66,7 +68,7 @@ class PHP_LexerGenerator_Regex_yyToken implements ArrayAccess
} }
} }
function offsetUnset($offset) function offsetUnset($offset): void
{ {
unset($this->metadata[$offset]); unset($this->metadata[$offset]);
} }

View File

@@ -575,6 +575,15 @@ class BinaryExpression extends Expression
case 'LIKE': case 'LIKE':
$sType = 'like'; $sType = 'like';
break; break;
case 'NOT LIKE':
$sType = 'notlike';
break;
case 'IN':
$sType = 'in';
break;
case 'NOT IN':
$sType = 'notin';
break;
default: default:
throw new Exception("Operator '$sOperator' not yet supported"); throw new Exception("Operator '$sOperator' not yet supported");
} }
@@ -639,7 +648,26 @@ class BinaryExpression extends Expression
case 'like': case 'like':
$sEscaped = preg_quote($mRight, '/'); $sEscaped = preg_quote($mRight, '/');
$sEscaped = str_replace(array('%', '_', '\\\\.*', '\\\\.'), array('.*', '.', '%', '_'), $sEscaped); $sEscaped = str_replace(array('%', '_', '\\\\.*', '\\\\.'), array('.*', '.', '%', '_'), $sEscaped);
$result = (int) preg_match("/$sEscaped/i", $mLeft); $pregRes = preg_match("/$sEscaped/i", $mLeft);
if ($pregRes === false) {
throw new Exception("Error in regular expression '$sEscaped'");
}
$result = ($pregRes === 1);
break;
case 'notlike':
$sEscaped = preg_quote($mRight, '/');
$sEscaped = str_replace(array('%', '_', '\\\\.*', '\\\\.'), array('.*', '.', '%', '_'), $sEscaped);
$pregRes = preg_match("/$sEscaped/i", $mLeft);
if ($pregRes === false) {
throw new Exception("Error in regular expression '$sEscaped'");
}
$result = ($pregRes !== 1);
break;
case 'in':
$result = in_array($mLeft, $mRight);
break;
case 'notin':
$result = !in_array($mLeft, $mRight);
break; break;
} }
return $result; return $result;
@@ -2250,7 +2278,12 @@ class ListExpression extends Expression
*/ */
public function Evaluate(array $aArgs) public function Evaluate(array $aArgs)
{ {
throw new Exception('list expression not yet supported'); //throw new Exception('list expression not yet supported');
$aResult = [];
foreach ($this->m_aExpressions as $oExpressions) {
$aResult[] = $oExpressions->Evaluate($aArgs);
}
return $aResult;
} }
/** /**

View File

@@ -235,7 +235,7 @@ class OQLLexerRaw
$match = false; $match = false;
foreach ($yy_yymore_patterns[$this->token] as $index => $rule) { foreach ($yy_yymore_patterns[$this->token] as $index => $rule) {
if (preg_match('/' . $rule . '/', if (preg_match('/' . $rule . '/',
$this->data, $yymatches, null, $this->count)) { $this->data, $yymatches, 0, $this->count)) {
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if ($match) { if ($match) {
if (strlen($yymatches[0]) > strlen($match[0][0])) { if (strlen($yymatches[0]) > strlen($match[0][0])) {

File diff suppressed because it is too large Load Diff

View File

@@ -71,28 +71,24 @@ class_list(A) ::= class_list(L) COMA class_name(X). {
where_statement(A) ::= WHERE condition(C). { A = C;} where_statement(A) ::= WHERE condition(C). { A = C;}
where_statement(A) ::= . { A = null;} where_statement(A) ::= . { A = null;}
join_statement(A) ::= join_item(J) join_statement(S). { join_statement(A) ::= join_statement(S) JOIN join_item(J). {
// insert the join statement on top of the existing list // insert the join statement on top of the existing list
array_unshift(S, J); array_push(S, J);
// and return the updated array // and return the updated array
A = S; A = S;
} }
join_statement(A) ::= join_item(J). { join_statement(A) ::= . { A = [];}
A = Array(J);
}
join_statement(A) ::= . { A = null;}
join_item(A) ::= JOIN class_name(X) AS_ALIAS class_name(Y) ON join_condition(C). join_item(A) ::= class_name(X) AS_ALIAS class_name(Y) ON join_condition(C).
{ {
// create an array with one single item // create an array with one single item
A = new OqlJoinSpec(X, Y, C); A = new OqlJoinSpec(X, Y, C);
} }
join_item(A) ::= JOIN class_name(X) ON join_condition(C). join_item(A) ::= class_name(X) ON join_condition(C).
{ {
// create an array with one single item // create an array with one single item
A = new OqlJoinSpec(X, X, C); A = new OqlJoinSpec(X, X, C);
} }
join_condition(A) ::= field_id(X) EQ field_id(Y). { A = new BinaryOqlExpression(X, '=', Y); } join_condition(A) ::= field_id(X) EQ field_id(Y). { A = new BinaryOqlExpression(X, '=', Y); }
join_condition(A) ::= field_id(X) BELOW field_id(Y). { A = new BinaryOqlExpression(X, 'BELOW', Y); } join_condition(A) ::= field_id(X) BELOW field_id(Y). { A = new BinaryOqlExpression(X, 'BELOW', Y); }
join_condition(A) ::= field_id(X) BELOW_STRICT field_id(Y). { A = new BinaryOqlExpression(X, 'BELOW_STRICT', Y); } join_condition(A) ::= field_id(X) BELOW_STRICT field_id(Y). { A = new BinaryOqlExpression(X, 'BELOW_STRICT', Y); }

View File

@@ -36,7 +36,13 @@ class UnknownClassOqlException extends OqlNormalizeException
{ {
public function __construct($sInput, OqlName $oName, $aExpecting = null) public function __construct($sInput, OqlName $oName, $aExpecting = null)
{ {
parent::__construct('Unknown class', $sInput, $oName, $aExpecting); $aAllowedClasses = [];
foreach ($aExpecting as $sClass) {
if (UserRights::IsActionAllowed($sClass, UR_ACTION_READ)) {
$aAllowedClasses[] = $sClass;
}
}
parent::__construct('Unknown class', $sInput, $oName, $aAllowedClasses);
} }
public function GetUserFriendlyDescription() public function GetUserFriendlyDescription()

View File

@@ -48,6 +48,42 @@ class ormDocument
* @since 3.1.0 * @since 3.1.0
*/ */
public const DEFAULT_DOWNLOADS_COUNT = 0; public const DEFAULT_DOWNLOADS_COUNT = 0;
private static $aKnownExtensions = [
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'dot' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'vsd' => 'application/x-visio',
'vdx' => 'application/visio.drawing',
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'zip' => 'application/zip',
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'exe' => 'application/octet-stream',
];
public static function GetKnownExtensions(): array
{
return self::$aKnownExtensions;
}
protected $m_data; protected $m_data;
protected $m_sMimeType; protected $m_sMimeType;
@@ -76,6 +112,36 @@ class ormDocument
$this->m_iDownloadsCount = $iDownloadsCount; $this->m_iDownloadsCount = $iDownloadsCount;
} }
/**
* @param string $sPath Absolute path of the document to read
*
* @return \ormDocument
* @throws \Exception
*/
public static function FromFile(string $sPath): ormDocument
{
$sPath = utils::RealPath($sPath, APPROOT);
if (false === $sPath) {
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
}
$sData = @file_get_contents($sPath);
if (false === $sData) {
throw new Exception("Failed to load the file '$sPath'. The file does not exist or the current process is not allowed to access it.");
}
$sExtension = strtolower(pathinfo($sPath, PATHINFO_EXTENSION));
$sFileName = basename($sPath);
$sMimeType = 'text/plain';
if (array_key_exists($sExtension, ormDocument::$aKnownExtensions)) {
$sMimeType = ormDocument::$aKnownExtensions[$sExtension];
} else if (extension_loaded('fileinfo')) {
$fInfo = new finfo(FILEINFO_MIME);
$sMimeType = $fInfo->file($sPath);
}
return new ormDocument($sData, $sMimeType, $sFileName);
}
public function __toString() public function __toString()
{ {
if($this->IsEmpty()) return ''; if($this->IsEmpty()) return '';
@@ -314,7 +380,7 @@ class ormDocument
'document' => $oDocument, 'document' => $oDocument,
'content_disposition' => $sContentDisposition, 'content_disposition' => $sContentDisposition,
); );
EventService::FireEvent(new EventData(EVENT_DOWNLOAD_DOCUMENT, $sClass, $aEventData)); EventService::FireEvent(new EventData(\EVENT_DOWNLOAD_DOCUMENT, $sClass, $aEventData));
$oPage->TrashUnexpectedOutput(); $oPage->TrashUnexpectedOutput();
$oPage->SetContentType($oDocument->GetMimeType()); $oPage->SetContentType($oDocument->GetMimeType());
$oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName()); $oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName());

View File

@@ -42,8 +42,8 @@ class iTopOwnershipToken extends DBObject
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes(); MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("acquired", array("allowed_values"=>null, "sql"=>'acquired', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("acquired", array("allowed_values"=>null, "sql"=>'acquired', "default_value"=>'NOW()', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("last_seen", array("allowed_values"=>null, "sql"=>'last_seen', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeDateTime("last_seen", array("allowed_values"=>null, "sql"=>'last_seen', "default_value"=>'NOW()', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values"=>null, "sql"=>'obj_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values"=>null, "sql"=>'obj_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values"=>null, "sql"=>'obj_key', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values"=>null, "sql"=>'obj_key', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("token", array("allowed_values"=>null, "sql"=>'token', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("token", array("allowed_values"=>null, "sql"=>'token', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));

View File

@@ -44,6 +44,8 @@ class ObjectResult
* @var string * @var string
* @api * @api
*/ */
use SanitizeTrait;
public $message; public $message;
/** /**
* @var mixed|null * @var mixed|null
@@ -156,6 +158,18 @@ class ObjectResult
{ {
$this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode, $bExtendedOutput); $this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode, $bExtendedOutput);
} }
public function SanitizeContent()
{
foreach($this->fields as $sFieldAttCode => $fieldValue) {
try {
$oAttDef = MetaModel::GetAttributeDef($this->class, $sFieldAttCode);
} catch (Exception $e) { // for special cases like ID
continue;
}
$this->SanitizeFieldIfSensitive($this->fields, $sFieldAttCode, $fieldValue, $oAttDef);
}
}
} }
@@ -221,6 +235,16 @@ class RestResultWithObjects extends RestResult
$sObjKey = get_class($oObject).'::'.$oObject->GetKey(); $sObjKey = get_class($oObject).'::'.$oObject->GetKey();
$this->objects[$sObjKey] = $oObjRes; $this->objects[$sObjKey] = $oObjRes;
} }
public function SanitizeContent()
{
parent::SanitizeContent();
foreach($this->objects as $sObjKey => $oObjRes)
{
$oObjRes->SanitizeContent();
}
}
} }
/** /**
@@ -308,9 +332,10 @@ class RestDelete
* *
* @package Core * @package Core
*/ */
class CoreServices implements iRestServiceProvider class CoreServices implements iRestServiceProvider, iRestInputSanitizer
{ {
/** use SanitizeTrait;
/**
* Enumerate services delivered by this class * Enumerate services delivered by this class
* *
* @param string $sVersion The version (e.g. 1.0) supported by the services * @param string $sVersion The version (e.g. 1.0) supported by the services
@@ -528,18 +553,18 @@ class CoreServices implements iRestServiceProvider
} }
else else
{ {
if (!$bExtendedOutput && RestUtils::GetOptionalParam($aParams, 'output_fields', '*') != '*') if (!$bExtendedOutput && RestUtils::GetOptionalParam($aParams, 'output_fields', '*') != '*')
{ {
$aFields = $aShowFields[$sClass]; $aFields = $aShowFields[$sClass];
//Id is not a valid attribute to optimize //Id is not a valid attribute to optimize
if (in_array('id', $aFields)) if (in_array('id', $aFields))
{ {
unset($aFields[array_search('id', $aFields)]); unset($aFields[array_search('id', $aFields)]);
} }
$aAttToLoad = array($oObjectSet->GetClassAlias() => $aFields); $aAttToLoad = array($oObjectSet->GetClassAlias() => $aFields);
$oObjectSet->OptimizeColumnLoad($aAttToLoad); $oObjectSet->OptimizeColumnLoad($aAttToLoad);
} }
while ($oObject = $oObjectSet->Fetch()) while ($oObject = $oObjectSet->Fetch())
{ {
$oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput); $oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
@@ -737,6 +762,33 @@ class CoreServices implements iRestServiceProvider
return $oResult; return $oResult;
} }
public function SanitizeJsonInput(string $sJsonInput): string
{
$sSanitizedJsonInput = $sJsonInput;
$aJsonData = json_decode($sSanitizedJsonInput, true);
$sOperation = $aJsonData['operation'];
switch ($sOperation) {
case 'core/check_credentials':
if (isset($aJsonData['password'])) {
$aJsonData['password'] = '*****';
}
break;
case 'core/update':
case 'core/create':
default :
$sClass = $aJsonData['class'];
if (isset($aJsonData['fields'])) {
foreach ($aJsonData['fields'] as $sFieldAttCode => $fieldValue) {
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFieldAttCode);
$this->SanitizeFieldIfSensitive($aJsonData['fields'], $sFieldAttCode, $fieldValue, $oAttDef);
}
}
break;
}
return json_encode($aJsonData, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
/** /**
* Helper for object deletion * Helper for object deletion
*/ */
@@ -875,3 +927,53 @@ class CoreServices implements iRestServiceProvider
return $iLimit * max(0, $iPage - 1); return $iLimit * max(0, $iPage - 1);
} }
} }
/**
* Sanitizes sensitive fields on a "json ready" representation of a DBObject
* Useful for logging purposes
*/
trait SanitizeTrait
{
/**
* Sanitize a field if it is sensitive.
*
* @param array $fields The fields array
* @param string $sFieldAttCode The attribute code
* @param mixed $oAttDef The attribute definition
* @throws Exception
*/
private function SanitizeFieldIfSensitive(array &$fields, string $sFieldAttCode, $fieldValue, $oAttDef): void
{
// for simple attribute
if ($oAttDef instanceof iAttributeNoGroupBy) { // iAttributeNoGroupBy is equivalent to sensitive attribute
$fields[$sFieldAttCode] = '*****';
return;
}
// for 1-n / n-n relation
if ($oAttDef instanceof AttributeLinkedSet) {
foreach ($fieldValue as $i => $aLnkValues) {
foreach ($aLnkValues as $sLnkAttCode => $sLnkValue) {
$oLnkAttDef = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $sLnkAttCode);
if ($oLnkAttDef instanceof iAttributeNoGroupBy) { // 1-n relation
$fields[$sFieldAttCode][$i][$sLnkAttCode] = '*****';
}
elseif ($oAttDef instanceof AttributeLinkedSetIndirect && $oLnkAttDef instanceof AttributeExternalField) { // for n-n relation
$oExtKeyAttDef = MetaModel::GetAttributeDef($oLnkAttDef->GetTargetClass(), $oLnkAttDef->GetExtAttCode());
if ($oExtKeyAttDef instanceof iAttributeNoGroupBy) {
$fields[$sFieldAttCode][$i][$sLnkAttCode] = '*****';
}
}
}
}
return;
}
// for external attribute
if ($oAttDef instanceof AttributeExternalField) {
$oExtKeyAttDef = MetaModel::GetAttributeDef($oAttDef->GetTargetClass(), $oAttDef->GetExtAttCode());
if ($oExtKeyAttDef instanceof iAttributeNoGroupBy) {
$fields[$sFieldAttCode] = '*****';
}
}
}
}

View File

@@ -500,17 +500,17 @@ EOF
if (file_exists($sDotExecutable)) if (file_exists($sDotExecutable))
{ {
// create the file with Graphviz // create the file with Graphviz
if (!is_dir(APPROOT."data")) if (!is_dir(utils::GetDataPath()))
{ {
@mkdir(APPROOT."data"); @mkdir(utils::GetDataPath());
} }
if (!is_dir(APPROOT."data/tmp")) if (!is_dir(utils::GetDataPath()."tmp"))
{ {
@mkdir(APPROOT."data/tmp"); @mkdir(utils::GetDataPath()."tmp");
} }
$sImageFilePath = tempnam(APPROOT."data/tmp", 'png-'); $sImageFilePath = tempnam(utils::GetDataPath()."tmp", 'png-');
$sDotDescription = $this->GetDotDescription(); $sDotDescription = $this->GetDotDescription();
$sDotFilePath = tempnam(APPROOT."data/tmp", 'dot-'); $sDotFilePath = tempnam(utils::GetDataPath()."tmp", 'dot-');
$rFile = @fopen($sDotFilePath, "w"); $rFile = @fopen($sDotFilePath, "w");
@fwrite($rFile, $sDotDescription); @fwrite($rFile, $sDotDescription);
@@ -556,17 +556,17 @@ EOF
if (file_exists($sDotExecutable)) if (file_exists($sDotExecutable))
{ {
// create the file with Graphviz // create the file with Graphviz
if (!is_dir(APPROOT."data")) if (!is_dir(utils::GetDataPath()))
{ {
@mkdir(APPROOT."data"); @mkdir(utils::GetDataPath());
} }
if (!is_dir(APPROOT."data/tmp")) if (!is_dir(utils::GetDataPath()."tmp"))
{ {
@mkdir(APPROOT."data/tmp"); @mkdir(utils::GetDataPath()."tmp");
} }
$sXdotFilePath = tempnam(APPROOT."data/tmp", 'xdot-'); $sXdotFilePath = tempnam(utils::GetDataPath()."tmp", 'xdot-');
$sDotDescription = $this->GetDotDescription(true); // true => don't put (localized) labels in the file, since it makes it harder to parse $sDotDescription = $this->GetDotDescription(true); // true => don't put (localized) labels in the file, since it makes it harder to parse
$sDotFilePath = tempnam(APPROOT."data/tmp", 'dot-'); $sDotFilePath = tempnam(utils::GetDataPath()."tmp", 'dot-');
$rFile = @fopen($sDotFilePath, "w"); $rFile = @fopen($sDotFilePath, "w");
@fwrite($rFile, $sDotDescription); @fwrite($rFile, $sDotDescription);

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
*/ */
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
/** /**
* A user defined trigger, to customize the application * A user defined trigger, to customize the application
* A trigger will activate an action * A trigger will activate an action
@@ -170,19 +172,20 @@ abstract class TriggerOnObject extends Trigger
{ {
$aParams = array $aParams = array
( (
"category" => "grant_by_profile,core/cmdb", "category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement", "key_type" => "autoincrement",
"name_attcode" => "description", "name_attcode" => "description",
"complementary_name_attcode" => ['finalclass', 'complement'], "complementary_name_attcode" => ['finalclass', 'complement'],
"state_attcode" => "", "state_attcode" => "",
"reconc_keys" => ['description'], "reconc_keys" => ['description'],
"db_table" => "priv_trigger_onobject", "db_table" => "priv_trigger_onobject",
"db_key_field" => "id", "db_key_field" => "id",
"db_finalclass_field" => "", "db_finalclass_field" => "",
); );
MetaModel::Init_Params($aParams); MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes(); MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeClass("target_class", array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeClass("target_class",
array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => "Attachment")));
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array()))); MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
// Display lists // Display lists
@@ -270,6 +273,36 @@ abstract class TriggerOnObject extends Trigger
} }
} }
/**
* if the target class is Attachment, then the trigger is read-only
* @param $sAttCode
* @param $aReasons
* @param $sTargetState
* @return int
* @throws ArchivedObjectException
* @throws CoreException
*/
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState='')
{
// Force the computed field to be read-only, preventing it to be written
if ($this->Get('target_class') == 'Attachment' ) {
return OPT_ATT_READONLY;
}
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
}
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
if ($this->Get('target_class') == 'Attachment' ) {
$oPage->AddUiBlock(AlertUIBlockFactory::MakeForWarning('', Dict::S('Class:TriggerOnObject:TriggerClassAttachment/ReadOnlyMessage')));
$oPage->add_ready_script("$('#UIMenuModify').hide();");
}
return $aHeaderBlocks;
}
/** /**
* Activate trigger based on attribute list given instead of changed attributes * Activate trigger based on attribute list given instead of changed attributes
* *
@@ -529,6 +562,7 @@ class TriggerOnObjectCreate extends TriggerOnObject
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form // MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
} }
} }
/** /**

View File

@@ -1875,54 +1875,6 @@ class UserRights
{ {
$aProfiles = self::$m_oAddOn->ListProfiles($oUser); $aProfiles = self::$m_oAddOn->ListProfiles($oUser);
} }
// portal ignored profiles
if(ContextTag::Check(ContextTag::TAG_PORTAL) && isset($_ENV['PORTAL_ID'])){
$aProfiles = self::FilterIgnoredPortalProfiles($aProfiles);
}
return $aProfiles;
}
/**
* Filter out profiles that are ignored by the `portal_ignored_profiles` configuration.
*
* Important: Administrator profile is always kept.
*
* N°2298 - switch on "portal user" profile when I go to portal even if I'm support agent
*
* @param $aProfiles array array of initial user profiles
*
* @return array array of user profiles without ignored ones
*/
private static function FilterIgnoredPortalProfiles(array $aProfiles) : array
{
// retrieve configuration
$aPortalIgnoredProfiles = MetaModel::GetModuleSetting('itop-portal-base', 'ignored_profiles');
// no ignored profiles configuration
if($aPortalIgnoredProfiles === null){
return $aProfiles;
}
// handle each configuration items...
foreach ($aPortalIgnoredProfiles as $aItem){
// test if portal instances covers current portal instance
$aPortalInstances = explode(',', $aItem['portal_instances_id']);
$aPortalInstances = array_map('trim', $aPortalInstances);
if(!in_array($_ENV['PORTAL_ID'], $aPortalInstances)){
continue;
}
// ignore configured profiles
$aIgnoredProfiles = explode(',', $aItem['profiles_to_ignore']);
$aIgnoredProfiles = array_map('trim', $aIgnoredProfiles);
$aProfiles = array_filter($aProfiles, function($sProfile) use ($aIgnoredProfiles) {
return $sProfile === 'Administrator' || !in_array(trim($sProfile), $aIgnoredProfiles);
});
}
return $aProfiles; return $aProfiles;
} }
@@ -1969,50 +1921,45 @@ class UserRights
*/ */
protected static function FindUser($sLogin, $sAuthentication = 'any', $bAllowDisabledUsers = false) protected static function FindUser($sLogin, $sAuthentication = 'any', $bAllowDisabledUsers = false)
{ {
if ($sAuthentication == 'any') if ($sAuthentication === 'any') {
{ $oUser = self::FindUser($sLogin, 'internal', $bAllowDisabledUsers);
$oUser = self::FindUser($sLogin, 'internal'); if ($oUser !== null) {
if ($oUser == null) return $oUser;
{
$oUser = self::FindUser($sLogin, 'external');
} }
return self::FindUser($sLogin, 'external', $bAllowDisabledUsers);
} }
else
{
if (!isset(self::$m_aCacheUsers))
{
self::$m_aCacheUsers = array('internal' => array(), 'external' => array());
}
if (!isset(self::$m_aCacheUsers[$sAuthentication][$sLogin])) if (!isset(self::$m_aCacheUsers)) {
{ self::$m_aCacheUsers = [ 'internal' => [], 'external' => [] ];
switch($sAuthentication)
{
case 'external':
$sBaseClass = 'UserExternal';
break;
case 'internal':
$sBaseClass = 'UserInternal';
break;
default:
echo "<p>sAuthentication = $sAuthentication</p>\n";
assert(false); // should never happen
}
$oSearch = DBObjectSearch::FromOQL("SELECT $sBaseClass WHERE login = :login");
$oSearch->AllowAllData();
if (!$bAllowDisabledUsers)
{
$oSearch->AddCondition('status', 'enabled');
}
$oSet = new DBObjectSet($oSearch, array(), array('login' => $sLogin));
$oUser = $oSet->fetch();
self::$m_aCacheUsers[$sAuthentication][$sLogin] = $oUser;
}
$oUser = self::$m_aCacheUsers[$sAuthentication][$sLogin];
} }
return $oUser;
if (! isset(self::$m_aCacheUsers[$sAuthentication]) || ! array_key_exists($sLogin, self::$m_aCacheUsers[$sAuthentication])) {
switch($sAuthentication) {
case 'external':
$sBaseClass = 'UserExternal';
break;
case 'internal':
$sBaseClass = 'UserInternal';
break;
default:
echo "<p>sAuthentication = $sAuthentication</p>\n";
assert(false); // should never happen
}
$oSearch = DBObjectSearch::FromOQL("SELECT $sBaseClass WHERE login = :login");
$oSearch->AllowAllData();
if (!$bAllowDisabledUsers) {
$oSearch->AddCondition('status', 'enabled');
}
$oSet = new DBObjectSet($oSearch, array(), array('login' => $sLogin));
$oUser = $oSet->fetch();
self::$m_aCacheUsers[$sAuthentication][$sLogin] = $oUser;
}
return self::$m_aCacheUsers[$sAuthentication][$sLogin];
} }
/** /**
@@ -2081,7 +2028,6 @@ class UserRights
{ {
return self::$m_sLastLoginStatus; return self::$m_sLastLoginStatus;
} }
} }
/** /**

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -3,18 +3,18 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-scrollbar--scrollbar-width: 8px !default; $ibo-scrollbar--scrollbar-width: $common-scrollbar--scrollbar-width !default;
$ibo-scrollbar--scrollbar-height: $ibo-scrollbar--scrollbar-width !default; /* For horizontal scrollbars */ $ibo-scrollbar--scrollbar-height: $common-scrollbar--scrollbar-height !default; /* For horizontal scrollbars */
$ibo-scrollbar--scrollbar-track-background-color: $ibo-color-transparent !default; $ibo-scrollbar--scrollbar-track-background-color: $common-scrollbar--scrollbar-track-background-color !default;
$ibo-scrollbar--scrollbar-track-border-radius: $ibo-border-radius-500 !default; $ibo-scrollbar--scrollbar-track-border-radius: $common-scrollbar--scrollbar-track-border-radius !default;
$ibo-scrollbar--scrollbar-thumb-background-color: $ibo-color-grey-300 !default; $ibo-scrollbar--scrollbar-thumb-background-color: $common-scrollbar--scrollbar-thumb-background-color !default;
$ibo-scrollbar--scrollbar-thumb-border: none !default; $ibo-scrollbar--scrollbar-thumb-border: none !default;
$ibo-scrollbar--scrollbar-thumb-border-radius: $ibo-border-radius-500 !default; $ibo-scrollbar--scrollbar-thumb-border-radius: $common-scrollbar--scrollbar-thumb-border-radius !default;
$ibo-svg-illustration--fill: $ibo-color-primary-500 !default; $ibo-svg-illustration--fill: $common-svg-illustration--fill !default;
$ibo-content-block--background-color: $ibo-color-white-100 !default; $ibo-content-block--background-color: $common-content-block--background-color !default;
$ibo-content-block--border: 1px solid $ibo-color-grey-400 !default; $ibo-content-block--border: $common-content-block--border !default;
/* CSS variables */ /* CSS variables */
:root{ :root{

View File

@@ -4,147 +4,3 @@
*/ */
/* This is an overload of the default lib. stylesheet to use local fonts instead of the CDN */ /* This is an overload of the default lib. stylesheet to use local fonts instead of the CDN */
@font-face {
font-family: Raleway;
font-weight: 100;
font-style: normal;
font-display: swap;
src: local('Raleway Thin'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-100-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 100;
font-style: italic;
font-display: swap;
src: local('Raleway Thin'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-100-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 200;
font-style: normal;
font-display: swap;
src: local('Raleway ExtraLight'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-200-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 200;
font-style: italic;
font-display: swap;
src: local('Raleway ExtraLight'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-200-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 300;
font-style: normal;
font-display: swap;
src: local('Raleway Light'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-300-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 300;
font-style: italic;
font-display: swap;
src: local('Raleway Light'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-300-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 400;
font-style: normal;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-400-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 400;
font-style: italic;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-400-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 500;
font-style: normal;
font-display: swap;
src: local('Raleway Medium'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-500-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 500;
font-style: italic;
font-display: swap;
src: local('Raleway Medium'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-500-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 600;
font-style: normal;
font-display: swap;
src: local('Raleway SemiBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-600-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 600;
font-style: italic;
font-display: swap;
src: local('Raleway SemiBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-600-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 700;
font-style: normal;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-700-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 700;
font-style: italic;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-700-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 800;
font-style: normal;
font-display: swap;
src: local('Raleway ExtraBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-800-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 800;
font-style: italic;
font-display: swap;
src: local('Raleway ExtraBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-800-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 900;
font-style: normal;
font-display: swap;
src: local('Raleway Black'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-900-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 900;
font-style: italic;
font-display: swap;
src: local('Raleway Black'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-900-italic.woff') format('woff'),
}

View File

@@ -14,8 +14,8 @@ $ibo-dm-class--Action--complementary-color: $ibo-color-white-100 !default;
.ibo-dm-class--Action { .ibo-dm-class--Action {
--ibo-main-color: #{$ibo-dm-class--Action--main-color}; --ibo-main-color: #{$ibo-dm-class--Action--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-class--Action--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-class--Action--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-class--Action--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-class--Action--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-class--Action--complementary-color}; --ibo-complementary-color: #{$ibo-dm-class--Action--complementary-color};
} }
@@ -35,8 +35,8 @@ $ibo-dm-enum--Action-status-enabled--complementary-color: $ibo-lifecycle-active-
.ibo-dm-enum--Action-status-enabled { .ibo-dm-enum--Action-status-enabled {
--ibo-main-color: #{$ibo-dm-enum--Action-status-enabled--main-color}; --ibo-main-color: #{$ibo-dm-enum--Action-status-enabled--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--Action-status-enabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--Action-status-enabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--Action-status-enabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--Action-status-enabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-enum--Action-status-enabled--complementary-color}; --ibo-complementary-color: #{$ibo-dm-enum--Action-status-enabled--complementary-color};
} }
@@ -56,8 +56,8 @@ $ibo-dm-enum--Action-status-disabled--complementary-color: $ibo-lifecycle-frozen
.ibo-dm-enum--Action-status-disabled { .ibo-dm-enum--Action-status-disabled {
--ibo-main-color: #{$ibo-dm-enum--Action-status-disabled--main-color}; --ibo-main-color: #{$ibo-dm-enum--Action-status-disabled--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--Action-status-disabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--Action-status-disabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--Action-status-disabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--Action-status-disabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-enum--Action-status-disabled--complementary-color}; --ibo-complementary-color: #{$ibo-dm-enum--Action-status-disabled--complementary-color};
} }
@@ -78,8 +78,8 @@ $ibo-dm-enum--Action-status-test--complementary-color: $ibo-lifecycle-inactive-s
.ibo-dm-enum--Action-status-test { .ibo-dm-enum--Action-status-test {
--ibo-main-color: #{$ibo-dm-enum--Action-status-test--main-color}; --ibo-main-color: #{$ibo-dm-enum--Action-status-test--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--Action-status-test--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--Action-status-test--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--Action-status-test--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--Action-status-test--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-enum--Action-status-test--complementary-color}; --ibo-complementary-color: #{$ibo-dm-enum--Action-status-test--complementary-color};
} }

View File

@@ -14,8 +14,8 @@ $ibo-dm-class--User--complementary-color: $ibo-color-white-100 !default;
.ibo-dm-class--User { .ibo-dm-class--User {
--ibo-main-color: #{$ibo-dm-class--User--main-color}; --ibo-main-color: #{$ibo-dm-class--User--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-class--User--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-class--User--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-class--User--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-class--User--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-class--User--complementary-color}; --ibo-complementary-color: #{$ibo-dm-class--User--complementary-color};
} }
.ibo-dm-class-alt--User { .ibo-dm-class-alt--User {
@@ -34,8 +34,8 @@ $ibo-dm-enum--User-status-enabled--complementary-color: $ibo-lifecycle-active-st
.ibo-dm-enum--User-status-enabled { .ibo-dm-enum--User-status-enabled {
--ibo-main-color: #{$ibo-dm-enum--User-status-enabled--main-color}; --ibo-main-color: #{$ibo-dm-enum--User-status-enabled--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--User-status-enabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--User-status-enabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--User-status-enabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--User-status-enabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-enum--User-status-enabled--complementary-color}; --ibo-complementary-color: #{$ibo-dm-enum--User-status-enabled--complementary-color};
} }
.ibo-dm-enum-alt--User-status-enabled { .ibo-dm-enum-alt--User-status-enabled {
@@ -54,8 +54,8 @@ $ibo-dm-enum--User-status-disabled--complementary-color: $ibo-lifecycle-inactive
.ibo-dm-enum--User-status-disabled { .ibo-dm-enum--User-status-disabled {
--ibo-main-color: #{$ibo-dm-enum--User-status-disabled--main-color}; --ibo-main-color: #{$ibo-dm-enum--User-status-disabled--main-color};
--ibo-main-color--100: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--User-status-disabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)}; --ibo-main-color--100: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--User-status-disabled--main-color, $ibo-color-base-lightness-100), $ibo-color-base-opacity-for-lightness-100)};
--ibo-main-color--900: #{ibo-adjust-alpha(ibo-adjust-lightness($ibo-dm-enum--User-status-disabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)}; --ibo-main-color--900: #{common-adjust-alpha(common-adjust-lightness($ibo-dm-enum--User-status-disabled--main-color, $ibo-color-base-lightness-900), $ibo-color-base-opacity-for-lightness-900)};
--ibo-complementary-color: #{$ibo-dm-enum--User-status-disabled--complementary-color}; --ibo-complementary-color: #{$ibo-dm-enum--User-status-disabled--complementary-color};
} }
.ibo-dm-enum-alt--User-status-disabled { .ibo-dm-enum-alt--User-status-disabled {

View File

@@ -2,7 +2,7 @@
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@import "../common/main";
@import "utils/all"; @import "utils/all";
@import "vendors/all"; @import "vendors/all";
@import "base/all"; @import "base/all";

View File

@@ -7,28 +7,20 @@
* Adjust the lightness of $sColor to the absolute $fTargetLightness value. * Adjust the lightness of $sColor to the absolute $fTargetLightness value.
* It is different than lighten() / darken() that shift the current lightness by X% * It is different than lighten() / darken() that shift the current lightness by X%
* *
* @deprecated Use common-adjust-lightness() instead
* @return Modified color value in HSLA format * @return Modified color value in HSLA format
*/ */
@function ibo-adjust-lightness($sColor, $fTargetLightness) { @function ibo-adjust-lightness($sColor, $fTargetLightness) {
$iHue: hue($sColor); @return common-adjust-lightness($sColor, $fTargetLightness);
$fSaturation: saturation($sColor);
$fLightness: lightness($sColor);
$fAlpha: alpha($sColor);
@return hsla($iHue, $fSaturation, $fTargetLightness, $fAlpha);
} }
/** /**
* Adjust the alpha chanel (opacity) of $sColor to the absolute $fTargetAlpha value. * Adjust the alpha chanel (opacity) of $sColor to the absolute $fTargetAlpha value.
* It is different than opacify() / transparentize() that shift the current alpha value by X% * It is different than opacify() / transparentize() that shift the current alpha value by X%
* *
* @deprecated Use common-adjust-alpha() instead
* @return Modified color value in HSLA format * @return Modified color value in HSLA format
*/ */
@function ibo-adjust-alpha($sColor, $fTargetAlpha) { @function ibo-adjust-alpha($sColor, $fTargetAlpha) {
$iHue: hue($sColor); @return common-adjust-alpha($sColor, $fTargetAlpha);
$fSaturation: saturation($sColor);
$fLightness: lightness($sColor);
$fAlpha: alpha($sColor);
@return hsla($iHue, $fSaturation, $fLightness, $fTargetAlpha);
} }

View File

@@ -3,9 +3,9 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-class-icon--small--size: 32px !default; $ibo-class-icon--small--size: $common-class-icon--small--size !default;
$ibo-class-icon--medium--size: 48px !default; $ibo-class-icon--medium--size: $common-class-icon--medium--size !default;
$ibo-class-icon--large--size: 64px !default; $ibo-class-icon--large--size: $common-class-icon--large--size !default;
.ibo-class-icon{ .ibo-class-icon{
&.ibo-is-small{ &.ibo-is-small{

View File

@@ -3,24 +3,7 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-text-colors: ( $ibo-text-colors: $common-text-colors !default;
'primary': $ibo-color-primary-800,
'secondary': $ibo-color-secondary-800,
'neutral': $ibo-color-secondary-800,
'information': $ibo-color-information-800,
'success': $ibo-color-success-800,
'failure': $ibo-color-danger-800,
'warning': $ibo-color-warning-800,
'danger': $ibo-color-danger-800,
'grey' : $ibo-color-grey-800,
'blue-grey': $ibo-color-blue-grey-800,
'blue': $ibo-color-blue-800,
'cyan': $ibo-color-cyan-800,
'green': $ibo-color-green-800,
'orange': $ibo-color-orange-800,
'red': $ibo-color-red-800,
'pink': $ibo-color-pink-800,
) !default;
@each $sColor, $sColorValue in $ibo-text-colors { @each $sColor, $sColorValue in $ibo-text-colors {
.ibo-text.ibo-is-#{$sColor} { .ibo-text.ibo-is-#{$sColor} {

View File

@@ -8,36 +8,3 @@
/* To use it, simply "@extend %fa-regular-base" in a rule and put the desired icon "content: '\f054'" */ /* To use it, simply "@extend %fa-regular-base" in a rule and put the desired icon "content: '\f054'" */
/******************************************************************************************************************************/ /******************************************************************************************************************************/
%fa-regular-base{
font-family: "Font Awesome 5 Free";
font-weight: 400;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
}
%fa-solid-base{
font-family: "Font Awesome 5 Free";
font-weight: 900;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
}
%fc-regular-base{
display: inline-block;
font-family: CombodoRegular;
font-style: normal;
font-variant: normal;
font-weight: normal;
text-rendering: auto;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -10,13 +10,13 @@
/***********************************************************************/ /***********************************************************************/
/* SCSS variables */ /* SCSS variables */
$ibo-sticky-sentinel--left: 0 !default; $ibo-sticky-sentinel--left: $common-sticky-sentinel--left !default;
$ibo-sticky-sentinel--right: 0 !default; $ibo-sticky-sentinel--right: $common-sticky-sentinel--right !default;
$ibo-sticky-sentinel--height: 0 !default; $ibo-sticky-sentinel--height: $common-sticky-sentinel--height !default;
$ibo-sticky-sentinel-top--top: 0 !default; $ibo-sticky-sentinel-top--top: $common-sticky-sentinel-top--top !default;
$ibo-sticky-sentinel-top--height: $ibo-sticky-sentinel--height !default; $ibo-sticky-sentinel-top--height: $common-sticky-sentinel-top--height !default;
$ibo-sticky-sentinel-bottom--bottom: 0 !default; $ibo-sticky-sentinel-bottom--bottom: $common-sticky-sentinel-bottom--bottom !default;
$ibo-sticky-sentinel-bottom--height: $ibo-sticky-sentinel--height !default; $ibo-sticky-sentinel-bottom--height: $common-sticky-sentinel-bottom--height !default;
/* Rules */ /* Rules */
.ibo-sticky-sentinel { .ibo-sticky-sentinel {

View File

@@ -1,26 +1,26 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
/* SCSS variables */ /* SCSS variables */
$ibo-has-description--content: "?" !default; $ibo-has-description--content: $common-has-description--content !default;
$ibo-has-description--padding-left: $ibo-spacing-200 !default; $ibo-has-description--padding-left: $common-has-description--padding-left !default;
$ibo-has-description--color: $ibo-color-grey-600 !default; $ibo-has-description--color: $common-has-description--color !default;
$ibo-has-description--font-size: 0.7em !default; /* Font size is em on purpose as we want it to be proportional to its context */ $ibo-has-description--font-size: $common-has-description--font-size !default; /* Font size is em on purpose as we want it to be proportional to its context */
$ibo-is-code--background-color: $ibo-color-white-200 !default; $ibo-is-code--background-color: $common-is-code--background-color !default;
$ibo-is-code--padding: 1.25rem 1.5rem !default; $ibo-is-code--padding: $common-is-code--padding !default;
$ibo-hyperlink-color: $ibo-color-primary-700 !default; $ibo-hyperlink-color: $common-hyperlink-color !default;
$ibo-hyperlink-text-decoration: none !default; $ibo-hyperlink-text-decoration: $common-hyperlink-text-decoration !default;
$ibo-hyperlink-color--on-hover: $ibo-color-primary-800 !default; $ibo-hyperlink-color--on-hover: $common-hyperlink-color--on-hover !default;
$ibo-hyperlink-text-decoration--on-hover: $ibo-hyperlink-text-decoration !default; $ibo-hyperlink-text-decoration--on-hover: $common-hyperlink-text-decoration--on-hover !default;
$ibo-hyperlink-color--on-active: $ibo-color-primary-900 !default; $ibo-hyperlink-color--on-active: $common-hyperlink-color--on-active !default;
$ibo-hyperlink-text-decoration--on-active: $ibo-hyperlink-text-decoration !default; $ibo-hyperlink-text-decoration--on-active: $common-hyperlink-text-decoration--on-active !default;
$ibo-figure--spacing-x: 2em !default; /* Mind that this matches Bulma rule for figure */ $ibo-figure--spacing-x: $common-figure--spacing-x !default; /* Mind that this matches Bulma rule for figure */
$ibo-figure--spacing-y: 2em !default; $ibo-figure--spacing-y: $common-figure--spacing-y !default;
/* CSS variables */ /* CSS variables */
:root{ :root{

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -3,8 +3,8 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-vertical-highlight--width: $ibo-size-100; $ibo-vertical-highlight--width: $common-vertical-highlight--width;
$ibo-vertical-highlight--height: 100%; $ibo-vertical-highlight--height: $common-vertical-highlight--height;
@mixin ibo-vertical-highlight { @mixin ibo-vertical-highlight {
display: block; display: block;

View File

@@ -3,18 +3,19 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-selectable--background-color: transparent !default; $ibo-selectable--background-color: $common-selectable--background-color !default;
$ibo-selectable--hover--color: $ibo-color-grey-100 !default; $ibo-selectable--hover--color: $common-selectable--hover--color !default;
$ibo-selectable--hover--background-color: $ibo-color-grey-600 !default; $ibo-selectable--hover--background-color: $common-selectable--hover--background-color !default;
$ibo-selectable--hover--background-opacity: 0.6 !default; $ibo-selectable--hover--background-opacity: $common-selectable--hover--background-opacity !default;
$ibo-selected--color: $ibo-color-grey-100 !default; $ibo-selected--color: $common-selected--color !default;
$ibo-selected--background-color: $ibo-color-grey-900 !default; $ibo-selected--background-color: $common-selected--background-color !default;
$ibo-selected--background-opacity: 0.5 !default; $ibo-selected--background-opacity: $common-selected--background-opacity !default;
$ibo-selected--hover--background-color: $common-selected--hover--background-color !default;
$ibo-selected--hover--background-opacity: $common-selected--hover--background-opacity !default;
$ibo-selected--hover--background-color: $ibo-color-grey-700 !default;
$ibo-selected--hover--background-opacity: 0.5 !default;
@mixin ibo-selectable { @mixin ibo-selectable {
content: ' '; content: ' ';
@extend %fa-solid-base; @extend %fa-solid-base;

View File

@@ -5,5 +5,5 @@
// These are the base variables used throughout the backoffice, if you don't know what to use, these are probably good :) // These are the base variables used throughout the backoffice, if you don't know what to use, these are probably good :)
$ibo-base-variable--text-color: $ibo-color-grey-900 !default; $ibo-base-variable--text-color: $common-base-variable--text-color !default;
$ibo-base-variable--border-radius: $ibo-border-radius-300 !default;; $ibo-base-variable--border-radius: $common-base-variable--border-radius !default;;

View File

@@ -3,13 +3,13 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-border-radius-100: 1px !default; $ibo-border-radius-100: $common-border-radius-100 !default;
$ibo-border-radius-300: 3px !default; $ibo-border-radius-300: $common-border-radius-300 !default;
$ibo-border-radius-400: 4px !default; $ibo-border-radius-400: $common-border-radius-400!default;
$ibo-border-radius-500: 5px !default; $ibo-border-radius-500: $common-border-radius-500 !default;
$ibo-border-radius-700: 10px !default; $ibo-border-radius-700: $common-border-radius-700 !default;
$ibo-border-radius-900: 16px !default; $ibo-border-radius-900: $common-border-radius-900 !default;
$ibo-border-radius-full: 100% !default; $ibo-border-radius-full: $common-border-radius-full !default;
:root{ :root{
--ibo-border-radius-100: #{$ibo-border-radius-100}; --ibo-border-radius-100: #{$ibo-border-radius-100};

View File

@@ -3,7 +3,7 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-depression-100: inset 0 1px 1px 0 rgba(0, 0, 0, 0.15) !default; $ibo-depression-100: $common-depression-100 !default;
:root{ :root{
--ibo-depression-100: #{$ibo-depression-100}; --ibo-depression-100: #{$ibo-depression-100};

View File

@@ -3,11 +3,11 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-elevation-100: 0 1px 2px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.12) !default; $ibo-elevation-100: $common-elevation-100 !default;
$ibo-elevation-200: 0 2px 4px rgba(0, 0, 0, 0.12), 0 3px 6px rgba(0, 0, 0, 0.15) !default; $ibo-elevation-200: $common-elevation-200 !default;
$ibo-elevation-300: 0 3px 6px rgba(0, 0, 0, 0.10), 0 10px 20px rgba(0, 0, 0, 0.15) !default; $ibo-elevation-300: $common-elevation-300 !default;
$ibo-elevation-400: 0 5px 10px rgba(0, 0, 0, 0.05), 0 15px 25px rgba(0, 0, 0, 0.15) !default; $ibo-elevation-400: $common-elevation-400 !default;
$ibo-elevation-500: 0 20px 40px rgba(0, 0, 0, 0.20) !default; $ibo-elevation-500: $common-elevation-500 !default;
:root{ :root{
--ibo-elevation-100: #{$ibo-elevation-100}; --ibo-elevation-100: #{$ibo-elevation-100};

View File

@@ -3,4 +3,3 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$approot-relative: '../../../../' !default;

View File

@@ -3,25 +3,25 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-size-0: 0 !default; $ibo-size-0: $common-size-0 !default;
$ibo-size-50: 2px !default; $ibo-size-50: $common-size-50 !default;
$ibo-size-100: 4px !default; $ibo-size-100: $common-size-100 !default;
$ibo-size-150: 8px !default; $ibo-size-150: $common-size-150 !default;
$ibo-size-200: 12px !default; $ibo-size-200: $common-size-200 !default;
$ibo-size-250: 16px !default; $ibo-size-250: $common-size-250 !default;
$ibo-size-300: 24px !default; $ibo-size-300: $common-size-300 !default;
$ibo-size-350: 32px !default; $ibo-size-350: $common-size-350 !default;
$ibo-size-400: 48px !default; $ibo-size-400: $common-size-400 !default;
$ibo-size-450: 64px !default; $ibo-size-450: $common-size-450 !default;
$ibo-size-500: 96px !default; $ibo-size-500: $common-size-500 !default;
$ibo-size-550: 128px !default; $ibo-size-550: $common-size-550 !default;
$ibo-size-600: 192px !default; $ibo-size-600: $common-size-600 !default;
$ibo-size-650: 256px !default; $ibo-size-650: $common-size-650 !default;
$ibo-size-700: 384px !default; $ibo-size-700: $common-size-700 !default;
$ibo-size-750: 512px !default; $ibo-size-750: $common-size-750 !default;
$ibo-size-800: 640px !default; $ibo-size-800: $common-size-800 !default;
$ibo-size-850: 768px !default; $ibo-size-850: $common-size-850 !default;
$ibo-size-900: 896px !default; $ibo-size-900: $common-size-900 !default;
:root{ :root{
--ibo-size-0: #{$ibo-size-0}; --ibo-size-0: #{$ibo-size-0};

View File

@@ -3,27 +3,28 @@
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
$ibo-spacing-0: $ibo-size-0 !default; $ibo-spacing-0: $common-spacing-0 !default;
$ibo-spacing-100: $ibo-size-50 !default; $ibo-spacing-100: $common-spacing-100 !default;
$ibo-spacing-200: $ibo-size-100 !default; $ibo-spacing-200: $common-spacing-200 !default;
$ibo-spacing-300: $ibo-size-150 !default; $ibo-spacing-300: $common-spacing-300 !default;
$ibo-spacing-400: $ibo-size-200 !default; $ibo-spacing-400: $common-spacing-400 !default;
$ibo-spacing-500: $ibo-size-250 !default; $ibo-spacing-500: $common-spacing-500 !default;
$ibo-spacing-600: $ibo-size-300 !default; $ibo-spacing-600: $common-spacing-600 !default;
$ibo-spacing-700: $ibo-size-350 !default; $ibo-spacing-700: $common-spacing-700 !default;
$ibo-spacing-800: $ibo-size-400 !default; $ibo-spacing-800: $common-spacing-800 !default;
$ibo-spacing-900: $ibo-size-450 !default; $ibo-spacing-900: $common-spacing-900 !default;
$ibo-spacing-950: $ibo-size-500 !default; $ibo-spacing-950: $common-spacing-950 !default;
:root{ :root{
--ibo-spacing-0: #{$ibo-size-0}; --ibo-spacing-0: #{$ibo-spacing-0};
--ibo-spacing-100: #{$ibo-size-50}; --ibo-spacing-100: #{$ibo-spacing-100};
--ibo-spacing-200: #{$ibo-size-100}; --ibo-spacing-200: #{$ibo-spacing-200};
--ibo-spacing-300: #{$ibo-size-150}; --ibo-spacing-300: #{$ibo-spacing-300};
--ibo-spacing-400: #{$ibo-size-200}; --ibo-spacing-400: #{$ibo-spacing-400};
--ibo-spacing-500: #{$ibo-size-250}; --ibo-spacing-500: #{$ibo-spacing-500};
--ibo-spacing-600: #{$ibo-size-300}; --ibo-spacing-600: #{$ibo-spacing-600};
--ibo-spacing-700: #{$ibo-size-350}; --ibo-spacing-700: #{$ibo-spacing-700};
--ibo-spacing-800: #{$ibo-size-400}; --ibo-spacing-800: #{$ibo-spacing-800};
--ibo-spacing-900: #{$ibo-size-450}; --ibo-spacing-900: #{$ibo-spacing-900};
--ibo-spacing-950: #{$ibo-spacing-950};
} }

View File

@@ -4,38 +4,38 @@
*/ */
/* Base size: html font-size 12px */ /* Base size: html font-size 12px */
$ibo-font-size-20: 0.67rem !default; /* 8px */ $ibo-font-size-20: $common-font-size-20 !default; /* 8px */
$ibo-font-size-50: 0.83rem !default; /* 10px */ $ibo-font-size-50: $common-font-size-50 !default; /* 10px */
$ibo-font-size-100: 1rem !default; /* 12px */ $ibo-font-size-100: $common-font-size-100 !default; /* 12px */
$ibo-font-size-150: 1.17rem !default; /* 14px */ $ibo-font-size-150: $common-font-size-150 !default; /* 14px */
$ibo-font-size-200: 1.33rem !default; /* 16px */ $ibo-font-size-200: $common-font-size-200 !default; /* 16px */
$ibo-font-size-250: 1.5rem !default; /* 18px */ $ibo-font-size-250: $common-font-size-250 !default; /* 18px */
$ibo-font-size-300: 1.67rem !default; /* 20px */ $ibo-font-size-300: $common-font-size-300 !default; /* 20px */
$ibo-font-size-350: 1.83rem !default; /* 22px */ $ibo-font-size-350: $common-font-size-350 !default; /* 22px */
$ibo-font-size-400: 2rem !default; /* 24px */ $ibo-font-size-400: $common-font-size-400 !default; /* 24px */
$ibo-font-size-450: 2.5rem !default; /* 30px */ $ibo-font-size-450: $common-font-size-450 !default; /* 30px */
$ibo-font-size-500: 3rem !default; /* 36px */ $ibo-font-size-500: $common-font-size-500 !default; /* 36px */
$ibo-font-size-550: 4rem !default; /* 48px */ $ibo-font-size-550: $common-font-size-550 !default; /* 48px */
$ibo-font-size-600: 5rem !default; /* 60px */ $ibo-font-size-600: $common-font-size-600 !default; /* 60px */
$ibo-font-size-650: 6rem !default; /* 72px */ $ibo-font-size-650: $common-font-size-650 !default; /* 72px */
$ibo-font-size-700: 7rem !default; /* 84px */ $ibo-font-size-700: $common-font-size-700 !default; /* 84px */
/* Value Common weight name (https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) */ /* Value Common weight name (https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) */
$ibo-font-weight-100: 100 !default; /* 100 Thin (Harline) */ $ibo-font-weight-100: $common-font-weight-100 !default; /* 100 Thin (Harline) */
$ibo-font-weight-200: 200 !default; /* 200 Extra Light (Ultra Light) */ $ibo-font-weight-200: $common-font-weight-200 !default; /* 200 Extra Light (Ultra Light) */
$ibo-font-weight-300: 300 !default; /* 300 Light */ $ibo-font-weight-300: $common-font-weight-300 !default; /* 300 Light */
$ibo-font-weight-400: 400 !default; /* 400 Normal (Regular) */ $ibo-font-weight-400: $common-font-weight-400 !default; /* 400 Normal (Regular) */
$ibo-font-weight-500: 500 !default; /* 500 Medium */ $ibo-font-weight-500: $common-font-weight-500 !default; /* 500 Medium */
$ibo-font-weight-600: 600 !default; /* 600 Semi Bold (Demi Bold) */ $ibo-font-weight-600: $common-font-weight-600 !default; /* 600 Semi Bold (Demi Bold) */
$ibo-font-weight-700: 700 !default; /* 700 Bold */ $ibo-font-weight-700: $common-font-weight-700 !default; /* 700 Bold */
$ibo-font-weight-800: 800 !default; /* 800 Extra Bold (Ultra Bold) */ $ibo-font-weight-800: $common-font-weight-800 !default; /* 800 Extra Bold (Ultra Bold) */
$ibo-font-weight-900: 900 !default; /* 900 Black (Heavy) */ $ibo-font-weight-900: $common-font-weight-900 !default; /* 900 Black (Heavy) */
$ibo-font-weight-950: 950 !default; /* 950 Extra Black (Ultra Black) */ $ibo-font-weight-950: $common-font-weight-950 !default; /* 950 Extra Black (Ultra Black) */
$ibo-font-family-base: "Raleway" !default; $ibo-font-family-base: $common-font-family-base !default;
$ibo-font-family-fallbacks: "sans-serif", "system-ui" !default; $ibo-font-family-fallbacks: $common-font-family-fallbacks !default;
$ibo-font-family-monospace: monospace !default; $ibo-font-family-monospace: $common-font-family-monospace !default;
$ibo-font-family-code: $ibo-font-family-monospace !default; $ibo-font-family-code: $common-font-family-code !default;
:root { :root {
--ibo-font-size-50: #{$ibo-font-size-50}; --ibo-font-size-50: #{$ibo-font-size-50};

View File

@@ -4,102 +4,124 @@
*/ */
/* Base color palettes */ /* Base color palettes */
$ibo-color-white-100: hsla(0, 0%, 100%, 1) !default; $ibo-color-white-100: $common-color-white-100 !default;
$ibo-color-white-200: hsla(0, 0%, 94.9%, 1) !default; $ibo-color-white-200: $common-color-white-200 !default;
$ibo-color-transparent: hsla(0, 0%, 100%, 0) !default; $ibo-color-transparent: $common-color-transparent !default;
$ibo-color-grey-50: hsla(240, 20%, 99%, 1) !default; $ibo-color-grey-50: $common-color-grey-50 !default;
$ibo-color-grey-100: hsla(210, 16.7%, 97.6%, 1) !default; $ibo-color-grey-100: $common-color-grey-100 !default;
$ibo-color-grey-200: hsla(207, 22.4%, 90.4%, 1) !default; $ibo-color-grey-200: $common-color-grey-200 !default;
$ibo-color-grey-300: hsla(210, 23.5%, 86.7%, 1) !default; $ibo-color-grey-300: $common-color-grey-300 !default;
$ibo-color-grey-400: hsla(208, 17.2%, 82.9%, 1) !default; $ibo-color-grey-400: $common-color-grey-400 !default;
$ibo-color-grey-500: hsla(209, 23.7%, 74.3%, 1) !default; $ibo-color-grey-500: $common-color-grey-500 !default;
$ibo-color-grey-600: hsla(215, 16.6%, 63.3%, 1) !default; $ibo-color-grey-600: $common-color-grey-600 !default;
$ibo-color-grey-700: hsla(214, 11.3%, 48.6%, 1) !default; $ibo-color-grey-700: $common-color-grey-700 !default;
$ibo-color-grey-800: hsla(215, 16.9%, 30.2%, 1) !default; $ibo-color-grey-800: $common-color-grey-800 !default;
$ibo-color-grey-900: hsla(215, 22.4%, 16.7%, 1) !default; $ibo-color-grey-900: $common-color-grey-900 !default;
$ibo-color-grey-950: hsla(215, 26.4%, 10.7%, 1) !default; $ibo-color-grey-950: $common-color-grey-950 !default;
$ibo-color-blue-grey-50: hsla(210, 36%, 96%, 1) !default; $ibo-color-blue-grey-50: $common-color-blue-grey-50 !default;
$ibo-color-blue-grey-100: hsla(198, 15.7%, 83.7%, 1) !default; $ibo-color-blue-grey-100: $common-color-blue-grey-100 !default;
$ibo-color-blue-grey-200: hsla(200, 15.3%, 73.1%, 1) !default; $ibo-color-blue-grey-200: $common-color-blue-grey-200 !default;
$ibo-color-blue-grey-300: hsla(200, 15.6%, 62.4%, 1) !default; $ibo-color-blue-grey-300: $common-color-blue-grey-300 !default;
$ibo-color-blue-grey-400: hsla(200, 15.4%, 54.1%, 1) !default; $ibo-color-blue-grey-400: $common-color-blue-grey-400 !default;
$ibo-color-blue-grey-500: hsla(200, 18.3%, 46.1%, 1) !default; $ibo-color-blue-grey-500: $common-color-blue-grey-500 !default;
$ibo-color-blue-grey-600: hsla(199, 18.4%, 40.4%, 1) !default; $ibo-color-blue-grey-600: $common-color-blue-grey-600 !default;
$ibo-color-blue-grey-700: hsla(199, 18.3%, 33.1%, 1) !default; $ibo-color-blue-grey-700: $common-color-blue-grey-700 !default;
$ibo-color-blue-grey-800: hsla(200, 17.9%, 26.3%, 1) !default; $ibo-color-blue-grey-800: $common-color-blue-grey-800 !default;
$ibo-color-blue-grey-900: hsla(200, 19.1%, 18.4%, 1) !default; $ibo-color-blue-grey-900: $common-color-blue-grey-900 !default;
$ibo-color-blue-grey-950: hsla(200, 20.2%, 13.1%, 1) !default; $ibo-color-blue-grey-950: $common-color-blue-grey-950 !default;
$ibo-color-blue-100: hsla(201, 100%, 96.1%, 1) !default; $ibo-color-blue-100: $common-color-blue-100 !default;
$ibo-color-blue-200: hsla(202, 80.6%, 85.9%, 1) !default; $ibo-color-blue-200: $common-color-blue-200 !default;
$ibo-color-blue-300: hsla(203, 82%, 76.1%, 1) !default; $ibo-color-blue-300: $common-color-blue-300 !default;
$ibo-color-blue-400: hsla(205, 79.3%, 65.9%, 1) !default; $ibo-color-blue-400: $common-color-blue-400 !default;
$ibo-color-blue-500: hsla(207, 72.6%, 57.1%, 1) !default; $ibo-color-blue-500: $common-color-blue-500 !default;
$ibo-color-blue-600: hsla(209, 61.6%, 50%, 1) !default; $ibo-color-blue-600: $common-color-blue-600 !default;
$ibo-color-blue-700: hsla(211, 60.7%, 42.9%, 1) !default; $ibo-color-blue-700: $common-color-blue-700 !default;
$ibo-color-blue-800: hsla(213, 49.4%, 34.1%, 1) !default; $ibo-color-blue-800: $common-color-blue-800 !default;
$ibo-color-blue-900: hsla(215, 41.3%, 28%, 1) !default; $ibo-color-blue-900: $common-color-blue-900 !default;
$ibo-color-blue-950: hsla(215, 36.8%, 23%, 1) !default; $ibo-color-blue-950: $common-color-blue-950 !default;
$ibo-color-cyan-100: hsla(186, 61.2%, 86.9%, 1) !default; $ibo-color-cyan-100: $common-color-cyan-100 !default;
$ibo-color-cyan-200: hsla(187, 71.6%, 71%, 1) !default; $ibo-color-cyan-200: $common-color-cyan-200 !default;
$ibo-color-cyan-300: hsla(187, 71.2%, 59.2%, 1) !default; $ibo-color-cyan-300: $common-color-cyan-300 !default;
$ibo-color-cyan-400: hsla(187, 70.9%, 50.2%, 1) !default; $ibo-color-cyan-400: $common-color-cyan-400 !default;
$ibo-color-cyan-500: hsla(187, 100%, 41.6%, 1) !default; $ibo-color-cyan-500: $common-color-cyan-500 !default;
$ibo-color-cyan-600: hsla(187, 100%, 37.8%, 1) !default; $ibo-color-cyan-600: $common-color-cyan-600 !default;
$ibo-color-cyan-700: hsla(186, 100%, 32.7%, 1) !default; $ibo-color-cyan-700: $common-color-cyan-700 !default;
$ibo-color-cyan-800: hsla(185, 100%, 28%, 1) !default; $ibo-color-cyan-800: $common-color-cyan-800 !default;
$ibo-color-cyan-900: hsla(182, 100%, 19.6%, 1) !default; $ibo-color-cyan-900: $common-color-cyan-900 !default;
$ibo-color-cyan-950: hsla(180, 100%, 10.6%, 1) !default; $ibo-color-cyan-950: $common-color-cyan-950 !default;
$ibo-color-green-100: hsla(88, 50.7%, 85.7%, 1) !default; $ibo-color-green-100: $common-color-green-100 !default;
$ibo-color-green-200: hsla(88, 50%, 76.5%, 1) !default; $ibo-color-green-200: $common-color-green-200 !default;
$ibo-color-green-300: hsla(88, 50%, 67.1%, 1) !default; $ibo-color-green-300: $common-color-green-300 !default;
$ibo-color-green-400: hsla(88, 50.2%, 59.8%, 1) !default; $ibo-color-green-400: $common-color-green-400 !default;
$ibo-color-green-500: hsla(88, 50.2%, 52.7%, 1) !default; $ibo-color-green-500: $common-color-green-500 !default;
$ibo-color-green-600: hsla(89, 46.1%, 48%, 1) !default; $ibo-color-green-600: $common-color-green-600 !default;
$ibo-color-green-700: hsla(92, 47.9%, 42.2%, 1) !default; $ibo-color-green-700: $common-color-green-700 !default;
$ibo-color-green-800: hsla(95, 49.5%, 36.5%, 1) !default; $ibo-color-green-800: $common-color-green-800 !default;
$ibo-color-green-900: hsla(103, 55.6%, 26.5%, 1) !default; $ibo-color-green-900: $common-color-green-900 !default;
$ibo-color-green-950: hsla(108, 59.6%, 21.5%, 1) !default; $ibo-color-green-950: $common-color-green-950 !default;
$ibo-color-orange-100: hsla(40, 100%, 97.1%, 1) !default; $ibo-color-orange-100: $common-color-orange-100 !default;
$ibo-color-orange-200: hsla(39, 96.4%, 89%, 1) !default; $ibo-color-orange-200: $common-color-orange-200 !default;
$ibo-color-orange-300: hsla(38, 93.2%, 76.9%, 1) !default; $ibo-color-orange-300: $common-color-orange-300 !default;
$ibo-color-orange-400: hsla(33, 89.9%, 64.9%, 1) !default; $ibo-color-orange-400: $common-color-orange-400 !default;
$ibo-color-orange-500: hsla(28, 82.9%, 51.8%, 1) !default; $ibo-color-orange-500: $common-color-orange-500 !default;
$ibo-color-orange-600: hsla(24, 74.7%, 49.6%, 1) !default; $ibo-color-orange-600: $common-color-orange-600 !default;
$ibo-color-orange-700: hsla(20, 70.7%, 44.1%, 1) !default; $ibo-color-orange-700: $common-color-orange-700 !default;
$ibo-color-orange-800: hsla(16, 65.1%, 37.1%, 1) !default; $ibo-color-orange-800: $common-color-orange-800 !default;
$ibo-color-orange-900: hsla(14, 60.8%, 30%, 1) !default; $ibo-color-orange-900: $common-color-orange-900 !default;
$ibo-color-orange-950: hsla(14, 55.1%, 22%, 1) !default; $ibo-color-orange-950: $common-color-orange-950 !default;
$ibo-color-red-100: hsla(0, 76.9%, 94.9%, 1) !default; $ibo-color-red-100: $common-color-red-100 !default;
$ibo-color-red-200: hsla(0, 95.1%, 92%, 1) !default; $ibo-color-red-200: $common-color-red-200 !default;
$ibo-color-red-300: hsla(0, 97.4%, 84.7%, 1) !default; $ibo-color-red-300: $common-color-red-300 !default;
$ibo-color-red-400: hsla(0, 95.3%, 74.7%, 1) !default; $ibo-color-red-400: $common-color-red-400 !default;
$ibo-color-red-500: hsla(0, 87.8%, 67.8%, 1) !default; $ibo-color-red-500: $common-color-red-500 !default;
$ibo-color-red-600: hsla(0, 76.3%, 57.1%, 1) !default; $ibo-color-red-600: $common-color-red-600 !default;
$ibo-color-red-700: hsla(0, 60.8%, 48%, 1) !default; $ibo-color-red-700: $common-color-red-700 !default;
$ibo-color-red-800: hsla(0, 55.8%, 39%, 1) !default; $ibo-color-red-800: $common-color-red-800 !default;
$ibo-color-red-900: hsla(0, 46.8%, 31%, 1) !default; $ibo-color-red-900: $common-color-red-900 !default;
$ibo-color-red-950: hsla(0, 42.9%, 20%, 1) !default; $ibo-color-red-950: $common-color-red-950 !default;
$ibo-color-pink-100: hsla(348, 100%, 98%, 1) !default; $ibo-color-pink-100: $common-color-pink-100 !default;
$ibo-color-pink-200: hsla(343, 95%, 92%, 1) !default; $ibo-color-pink-200: $common-color-pink-200 !default;
$ibo-color-pink-300: hsla(339, 90%, 85%, 1) !default; $ibo-color-pink-300: $common-color-pink-300 !default;
$ibo-color-pink-400: hsla(336, 86%, 75%, 1) !default; $ibo-color-pink-400: $common-color-pink-400 !default;
$ibo-color-pink-500: hsla(331, 79%, 66%, 1) !default; $ibo-color-pink-500: $common-color-pink-500 !default;
$ibo-color-pink-600: hsla(329, 64%, 54%, 1) !default; $ibo-color-pink-600: $common-color-pink-600 !default;
$ibo-color-pink-700: hsla(325, 57%, 46%, 1) !default; $ibo-color-pink-700: $common-color-pink-700 !default;
$ibo-color-pink-800: hsla(322, 60%, 37%, 1) !default; $ibo-color-pink-800: $common-color-pink-800 !default;
$ibo-color-pink-900: hsla(318, 51%, 29%, 1) !default; $ibo-color-pink-900: $common-color-pink-900 !default;
$ibo-color-pink-950: hsla(318, 51%, 21%, 1) !default; $ibo-color-pink-950: $common-color-pink-950 !default;
$ibo-colors: ('grey', 'blue-grey', 'blue', 'cyan', 'green', 'orange', 'red', 'pink', 'primary', 'secondary', 'information', 'success', 'warning', 'danger'); $ibo-color-yellow-100: $common-color-yellow-100 !default;
$ibo-color-yellow-200: $common-color-yellow-200 !default;
$ibo-color-yellow-300: $common-color-yellow-300 !default;
$ibo-color-yellow-400: $common-color-yellow-400 !default;
$ibo-color-yellow-500: $common-color-yellow-500 !default;
$ibo-color-yellow-600: $common-color-yellow-600 !default;
$ibo-color-yellow-700: $common-color-yellow-700 !default;
$ibo-color-yellow-800: $common-color-yellow-800 !default;
$ibo-color-yellow-900: $common-color-yellow-900 !default;
$ibo-color-yellow-950: $common-color-yellow-950 !default;
$ibo-color-purple-100: $common-color-purple-100 !default;
$ibo-color-purple-200: $common-color-purple-200 !default;
$ibo-color-purple-300: $common-color-purple-300 !default;
$ibo-color-purple-400: $common-color-purple-400 !default;
$ibo-color-purple-500: $common-color-purple-500 !default;
$ibo-color-purple-600: $common-color-purple-600 !default;
$ibo-color-purple-700: $common-color-purple-700 !default;
$ibo-color-purple-800: $common-color-purple-800 !default;
$ibo-color-purple-900: $common-color-purple-900 !default;
$ibo-color-purple-950: $common-color-purple-950 !default;
$ibo-colors: $common-colors;
/* CSS variables */ /* CSS variables */
:root{ :root{
@@ -196,4 +218,26 @@ $ibo-colors: ('grey', 'blue-grey', 'blue', 'cyan', 'green', 'orange', 'red', 'pi
--ibo-color-pink-800: #{$ibo-color-pink-800}; --ibo-color-pink-800: #{$ibo-color-pink-800};
--ibo-color-pink-900: #{$ibo-color-pink-900}; --ibo-color-pink-900: #{$ibo-color-pink-900};
--ibo-color-pink-950: #{$ibo-color-pink-950}; --ibo-color-pink-950: #{$ibo-color-pink-950};
--ibo-color-yellow-100: #{$ibo-color-yellow-100};
--ibo-color-yellow-200: #{$ibo-color-yellow-200};
--ibo-color-yellow-300: #{$ibo-color-yellow-300};
--ibo-color-yellow-400: #{$ibo-color-yellow-400};
--ibo-color-yellow-500: #{$ibo-color-yellow-500};
--ibo-color-yellow-600: #{$ibo-color-yellow-600};
--ibo-color-yellow-700: #{$ibo-color-yellow-700};
--ibo-color-yellow-800: #{$ibo-color-yellow-800};
--ibo-color-yellow-900: #{$ibo-color-yellow-900};
--ibo-color-yellow-950: #{$ibo-color-yellow-950};
--ibo-color-purple-100: #{$ibo-color-purple-100};
--ibo-color-purple-200: #{$ibo-color-purple-200};
--ibo-color-purple-300: #{$ibo-color-purple-300};
--ibo-color-purple-400: #{$ibo-color-purple-400};
--ibo-color-purple-500: #{$ibo-color-purple-500};
--ibo-color-purple-600: #{$ibo-color-purple-600};
--ibo-color-purple-700: #{$ibo-color-purple-700};
--ibo-color-purple-800: #{$ibo-color-purple-800};
--ibo-color-purple-900: #{$ibo-color-purple-900};
--ibo-color-purple-950: #{$ibo-color-purple-950};
} }

View File

@@ -5,8 +5,8 @@
/* Base helpers for colors */ /* Base helpers for colors */
/* - These lightness vars are used to force a certain lightness on HSLA colors */ /* - These lightness vars are used to force a certain lightness on HSLA colors */
$ibo-color-base-lightness-100: 93% !default; $ibo-color-base-lightness-100: $common-color-base-lightness-100 !default;
$ibo-color-base-lightness-900: 15% !default; $ibo-color-base-lightness-900: $common-color-base-lightness-900 !default;
$ibo-color-base-opacity-for-lightness-100: 1 !default; $ibo-color-base-opacity-for-lightness-100: $common-color-base-opacity-for-lightness-100 !default;
$ibo-color-base-opacity-for-lightness-900: 1 !default; $ibo-color-base-opacity-for-lightness-900: $common-color-base-opacity-for-lightness-900 !default;

View File

@@ -5,24 +5,24 @@
/* Lifecycle palette */ /* Lifecycle palette */
/* - For workflow */ /* - For workflow */
$ibo-lifecycle-new-state-primary-color: $ibo-color-blue-800 !default; $ibo-lifecycle-new-state-primary-color: $common-lifecycle-new-state-primary-color !default;
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-new-state-secondary-color: $common-lifecycle-new-state-secondary-color !default;
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-blue-800 !default; $ibo-lifecycle-neutral-state-primary-color: $common-lifecycle-neutral-state-primary-color !default;
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-neutral-state-secondary-color: $common-lifecycle-neutral-state-secondary-color !default;
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-orange-400 !default; $ibo-lifecycle-waiting-state-primary-color: $common-lifecycle-waiting-state-primary-color !default;
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-waiting-state-secondary-color: $common-lifecycle-waiting-state-secondary-color !default;
$ibo-lifecycle-success-state-primary-color: $ibo-color-green-700 !default; $ibo-lifecycle-success-state-primary-color: $common-lifecycle-success-state-primary-color !default;
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-success-state-secondary-color: $common-lifecycle-success-state-secondary-color !default;
$ibo-lifecycle-failure-state-primary-color: $ibo-color-pink-700 !default; $ibo-lifecycle-failure-state-primary-color: $common-lifecycle-failure-state-primary-color !default;
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-failure-state-secondary-color: $common-lifecycle-failure-state-secondary-color !default;
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-grey-200 !default; $ibo-lifecycle-frozen-state-primary-color: $common-lifecycle-frozen-state-primary-color !default;
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-grey-700 !default; $ibo-lifecycle-frozen-state-secondary-color: $common-lifecycle-frozen-state-secondary-color !default;
/* - For basic lifecycle */ /* - For basic lifecycle */
$ibo-lifecycle-active-state-primary-color: $ibo-color-green-700 !default; $ibo-lifecycle-active-state-primary-color: $common-lifecycle-active-state-primary-color !default;
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-active-state-secondary-color: $common-lifecycle-active-state-secondary-color !default;
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-orange-400 !default; $ibo-lifecycle-inactive-state-primary-color: $common-lifecycle-inactive-state-primary-color !default;
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100 !default; $ibo-lifecycle-inactive-state-secondary-color: $common-lifecycle-inactive-state-secondary-color !default;
$ibo-lifecycle-states-colors: ( $ibo-lifecycle-states-colors: (
'new': ( 'new': (

View File

@@ -5,99 +5,99 @@
/* Semantic palettes */ /* Semantic palettes */
/* - Primary color of the brand */ /* - Primary color of the brand */
$ibo-color-primary-100: $ibo-color-orange-100 !default; $ibo-color-primary-100: $common-color-primary-100 !default;
$ibo-color-primary-200: $ibo-color-orange-200 !default; $ibo-color-primary-200: $common-color-primary-200 !default;
$ibo-color-primary-300: $ibo-color-orange-300 !default; $ibo-color-primary-300: $common-color-primary-300 !default;
$ibo-color-primary-400: $ibo-color-orange-400 !default; $ibo-color-primary-400: $common-color-primary-400 !default;
$ibo-color-primary-500: $ibo-color-orange-500 !default; $ibo-color-primary-500: $common-color-primary-500 !default;
$ibo-color-primary-600: $ibo-color-orange-600 !default; $ibo-color-primary-600: $common-color-primary-600 !default;
$ibo-color-primary-700: $ibo-color-orange-700 !default; $ibo-color-primary-700: $common-color-primary-700 !default;
$ibo-color-primary-800: $ibo-color-orange-800 !default; $ibo-color-primary-800: $common-color-primary-800 !default;
$ibo-color-primary-900: $ibo-color-orange-900 !default; $ibo-color-primary-900: $common-color-primary-900 !default;
$ibo-color-primary-950: $ibo-color-orange-950 !default; $ibo-color-primary-950: $common-color-primary-950 !default;
/* - Secondary color of the brand */ /* - Secondary color of the brand */
$ibo-color-secondary-100: $ibo-color-grey-100 !default; $ibo-color-secondary-100: $common-color-secondary-100 !default;
$ibo-color-secondary-200: $ibo-color-grey-200 !default; $ibo-color-secondary-200: $common-color-secondary-200 !default;
$ibo-color-secondary-300: $ibo-color-grey-300 !default; $ibo-color-secondary-300: $common-color-secondary-300 !default;
$ibo-color-secondary-400: $ibo-color-grey-400 !default; $ibo-color-secondary-400: $common-color-secondary-400 !default;
$ibo-color-secondary-500: $ibo-color-grey-500 !default; $ibo-color-secondary-500: $common-color-secondary-500 !default;
$ibo-color-secondary-600: $ibo-color-grey-600 !default; $ibo-color-secondary-600: $common-color-secondary-600 !default;
$ibo-color-secondary-700: $ibo-color-grey-700 !default; $ibo-color-secondary-700: $common-color-secondary-700 !default;
$ibo-color-secondary-800: $ibo-color-grey-800 !default; $ibo-color-secondary-800: $common-color-secondary-800 !default;
$ibo-color-secondary-900: $ibo-color-grey-900 !default; $ibo-color-secondary-900: $common-color-secondary-900 !default;
$ibo-color-secondary-950: $ibo-color-grey-950 !default; $ibo-color-secondary-950: $common-color-secondary-950 !default;
/* - Information: messages / actions that should neither seem as success, warning or failure */ /* - Information: messages / actions that should neither seem as success, warning or failure */
$ibo-color-information-100: $ibo-color-blue-100 !default; $ibo-color-information-100: $common-color-information-100 !default;
$ibo-color-information-200: $ibo-color-blue-200 !default; $ibo-color-information-200: $common-color-information-200 !default;
$ibo-color-information-300: $ibo-color-blue-300 !default; $ibo-color-information-300: $common-color-information-300 !default;
$ibo-color-information-400: $ibo-color-blue-400 !default; $ibo-color-information-400: $common-color-information-400 !default;
$ibo-color-information-500: $ibo-color-blue-500 !default; $ibo-color-information-500: $common-color-information-500 !default;
$ibo-color-information-600: $ibo-color-blue-600 !default; $ibo-color-information-600: $common-color-information-600 !default;
$ibo-color-information-700: $ibo-color-blue-700 !default; $ibo-color-information-700: $common-color-information-700 !default;
$ibo-color-information-800: $ibo-color-blue-800 !default; $ibo-color-information-800: $common-color-information-800 !default;
$ibo-color-information-900: $ibo-color-blue-900 !default; $ibo-color-information-900: $common-color-information-900 !default;
$ibo-color-information-950: $ibo-color-blue-950 !default; $ibo-color-information-950: $common-color-information-950 !default;
/* Success: messages of success, safe actions, ... */ /* Success: messages of success, safe actions, ... */
$ibo-color-success-100: $ibo-color-green-100 !default; $ibo-color-success-100: $common-color-success-100 !default;
$ibo-color-success-200: $ibo-color-green-200 !default; $ibo-color-success-200: $common-color-success-200 !default;
$ibo-color-success-300: $ibo-color-green-300 !default; $ibo-color-success-300: $common-color-success-300 !default;
$ibo-color-success-400: $ibo-color-green-400 !default; $ibo-color-success-400: $common-color-success-400 !default;
$ibo-color-success-500: $ibo-color-green-500 !default; $ibo-color-success-500: $common-color-success-500 !default;
$ibo-color-success-600: $ibo-color-green-600 !default; $ibo-color-success-600: $common-color-success-600 !default;
$ibo-color-success-700: $ibo-color-green-700 !default; $ibo-color-success-700: $common-color-success-700 !default;
$ibo-color-success-800: $ibo-color-green-800 !default; $ibo-color-success-800: $common-color-success-800 !default;
$ibo-color-success-900: $ibo-color-green-900 !default; $ibo-color-success-900: $common-color-success-900 !default;
$ibo-color-success-950: $ibo-color-green-950 !default; $ibo-color-success-950: $common-color-success-950 !default;
/* Warning: messages of warning, actions that would be done carefully, ... */ /* Warning: messages of warning, actions that would be done carefully, ... */
$ibo-color-warning-100: $ibo-color-orange-100 !default; $ibo-color-warning-100: $common-color-warning-100 !default;
$ibo-color-warning-200: $ibo-color-orange-200 !default; $ibo-color-warning-200: $common-color-warning-200 !default;
$ibo-color-warning-300: $ibo-color-orange-300 !default; $ibo-color-warning-300: $common-color-warning-300 !default;
$ibo-color-warning-400: $ibo-color-orange-400 !default; $ibo-color-warning-400: $common-color-warning-400 !default;
$ibo-color-warning-500: $ibo-color-orange-500 !default; $ibo-color-warning-500: $common-color-warning-500 !default;
$ibo-color-warning-600: $ibo-color-orange-600 !default; $ibo-color-warning-600: $common-color-warning-600 !default;
$ibo-color-warning-700: $ibo-color-orange-700 !default; $ibo-color-warning-700: $common-color-warning-700 !default;
$ibo-color-warning-800: $ibo-color-orange-800 !default; $ibo-color-warning-800: $common-color-warning-800 !default;
$ibo-color-warning-900: $ibo-color-orange-900 !default; $ibo-color-warning-900: $common-color-warning-900 !default;
$ibo-color-warning-950: $ibo-color-orange-950 !default; $ibo-color-warning-950: $common-color-warning-950 !default;
/* Danger: messages of failure, error, ... */ /* Danger: messages of failure, error, ... */
$ibo-color-error-100: $ibo-color-red-100 !default; $ibo-color-error-100: $common-color-error-100 !default;
$ibo-color-error-200: $ibo-color-red-200 !default; $ibo-color-error-200: $common-color-error-200 !default;
$ibo-color-error-300: $ibo-color-red-300 !default; $ibo-color-error-300: $common-color-error-300 !default;
$ibo-color-error-400: $ibo-color-red-400 !default; $ibo-color-error-400: $common-color-error-400 !default;
$ibo-color-error-500: $ibo-color-red-500 !default; $ibo-color-error-500: $common-color-error-500 !default;
$ibo-color-error-600: $ibo-color-red-600 !default; $ibo-color-error-600: $common-color-error-600 !default;
$ibo-color-error-700: $ibo-color-red-700 !default; $ibo-color-error-700: $common-color-error-700 !default;
$ibo-color-error-800: $ibo-color-red-800 !default; $ibo-color-error-800: $common-color-error-800 !default;
$ibo-color-error-900: $ibo-color-red-900 !default; $ibo-color-error-900: $common-color-error-900 !default;
$ibo-color-error-950: $ibo-color-red-950 !default; $ibo-color-error-950: $common-color-error-950 !default;
/* Danger: messages of danger, actions that cannot be undone, ... */ /* Danger: messages of danger, actions that cannot be undone, ... */
$ibo-color-danger-100: $ibo-color-red-100 !default; $ibo-color-danger-100: $common-color-danger-100 !default;
$ibo-color-danger-200: $ibo-color-red-200 !default; $ibo-color-danger-200: $common-color-danger-200 !default;
$ibo-color-danger-300: $ibo-color-red-300 !default; $ibo-color-danger-300: $common-color-danger-300 !default;
$ibo-color-danger-400: $ibo-color-red-400 !default; $ibo-color-danger-400: $common-color-danger-400 !default;
$ibo-color-danger-500: $ibo-color-red-500 !default; $ibo-color-danger-500: $common-color-danger-500 !default;
$ibo-color-danger-600: $ibo-color-red-600 !default; $ibo-color-danger-600: $common-color-danger-600 !default;
$ibo-color-danger-700: $ibo-color-red-700 !default; $ibo-color-danger-700: $common-color-danger-700 !default;
$ibo-color-danger-800: $ibo-color-red-800 !default; $ibo-color-danger-800: $common-color-danger-800 !default;
$ibo-color-danger-900: $ibo-color-red-900 !default; $ibo-color-danger-900: $common-color-danger-900 !default;
$ibo-color-danger-950: $ibo-color-red-950 !default; $ibo-color-danger-950: $common-color-danger-950 !default;
$ibo-semantic-colors: ('primary', 'secondary', 'information', 'success', 'warning', 'danger'); $ibo-semantic-colors: $common-semantic-colors !default;
$ibo-caselog-highlight-color-1: $ibo-color-green-700 !default; $ibo-caselog-highlight-color-1: $common-caselog-highlight-color-1 !default;
$ibo-caselog-highlight-color-2: $ibo-color-pink-700 !default; $ibo-caselog-highlight-color-2: $common-caselog-highlight-color-2 !default;
$ibo-caselog-highlight-color-3: $ibo-color-orange-400 !default; $ibo-caselog-highlight-color-3: $common-caselog-highlight-color-3 !default;
$ibo-caselog-highlight-color-4: $ibo-color-blue-600 !default; $ibo-caselog-highlight-color-4: $common-caselog-highlight-color-4 !default;
$ibo-caselog-highlight-color-5: $ibo-color-cyan-200 !default; $ibo-caselog-highlight-color-5: $common-caselog-highlight-color-5 !default;
$ibo-caselog-highlight-color-6: $ibo-color-green-200 !default; $ibo-caselog-highlight-color-6: $common-caselog-highlight-color-6 !default;
$ibo-caselog-highlight-color-7: $ibo-color-pink-300 !default; $ibo-caselog-highlight-color-7: $common-caselog-highlight-color-7 !default;
$ibo-caselog-highlight-colors: ($ibo-caselog-highlight-color-1, $ibo-caselog-highlight-color-2, $ibo-caselog-highlight-color-3, $ibo-caselog-highlight-color-4, $ibo-caselog-highlight-color-5, $ibo-caselog-highlight-color-6, $ibo-caselog-highlight-color-7) !default; $ibo-caselog-highlight-colors: $common-caselog-highlight-colors !default;
/* CSS variables */ /* CSS variables */
:root { :root {

View File

@@ -6,8 +6,8 @@
/* Skeleton palette */ /* Skeleton palette */
/* - Colors used by skeletons svg to display placeholders */ /* - Colors used by skeletons svg to display placeholders */
$ibo-skeleton-start-color: $ibo-color-grey-200 !default; $ibo-skeleton-start-color: $common-skeleton-start-color !default;
$ibo-skeleton-stop-color: $ibo-color-blue-grey-100 !default; $ibo-skeleton-stop-color: $common-skeleton-stop-color !default;
/* CSS variables */ /* CSS variables */
/* Skeleton CSS3 variables are not ibo prefixed as they are not iTop backoffice exclusives*/ /* Skeleton CSS3 variables are not ibo prefixed as they are not iTop backoffice exclusives*/

View File

@@ -2,44 +2,115 @@
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@import "../../common/vendors/_highlightjs";
// Backoffice specific variables // Backoffice specific variables
$ibo-vendors-highlightjs--padding: 0.9rem !default; $ibo-vendors-highlightjs--padding: $common-vendors-highlightjs--padding !default;
$ibo-vendors-highlightjs--box-shadow: 0 0px 3px 2px inset rgba(0, 0, 0, 0.4) !default; $ibo-vendors-highlightjs--box-shadow: $common-vendors-highlightjs--box-shadow !default;
$ibo-vendors-highlightjs--border-radius: $ibo-border-radius-300 !default; $ibo-vendors-highlightjs--border-radius: $common-vendors-highlightjs--border-radius !default;
$ibo-vendors-highlightjs--code--padding-x: 5px !default; $ibo-vendors-highlightjs--code--padding-x: $common-vendors-highlightjs--code--padding-x !default;
$ibo-vendors-highlightjs--code--padding-y: 3px !default; $ibo-vendors-highlightjs--code--padding-y: $common-vendors-highlightjs--code--padding-y !default;
$ibo-vendors-highlightjs--background-color: #282b2e !default; $ibo-vendors-highlightjs--background-color: $common-vendors-highlightjs--background-color !default;
$ibo-vendors-highlightjs--color: #e0e2e4 !default; $ibo-vendors-highlightjs--color: $common-vendors-highlightjs--color !default;
$ibo-vendors-highlightjs--keyword--color: #93c763 !default; $ibo-vendors-highlightjs--keyword--color: $common-vendors-highlightjs--keyword--color !default;
$ibo-vendors-highlightjs--number--color: #ffcd22 !default; $ibo-vendors-highlightjs--number--color: $common-vendors-highlightjs--number--color !default;
$ibo-vendors-highlightjs--attribute--color: #668bb0 !default; $ibo-vendors-highlightjs--attribute--color: $common-vendors-highlightjs--attribute--color !default;
$ibo-vendors-highlightjs--regexp--color: #d39745 !default; $ibo-vendors-highlightjs--regexp--color: $common-vendors-highlightjs--regexp--color !default;
$ibo-vendors-highlightjs--meta--color: #557182 !default; $ibo-vendors-highlightjs--meta--color: $common-vendors-highlightjs--meta--color !default;
$ibo-vendors-highlightjs--tag--color: #8cbbad !default; $ibo-vendors-highlightjs--tag--color: $common-vendors-highlightjs--tag--color !default;
$ibo-vendors-highlightjs--string--color: #ec7600 !default; $ibo-vendors-highlightjs--string--color: $common-vendors-highlightjs--string--color !default;
$ibo-vendors-highlightjs--comment--color: #818e96 !default; $ibo-vendors-highlightjs--comment--color: $common-vendors-highlightjs--comment--color !default;
$ibo-vendors-highlightjs--selector-class--color: #A082BD !default; $ibo-vendors-highlightjs--selector-class--color: $common-vendors-highlightjs--selector-class--color !default;
$ibo-vendors-highlightjs--code--color: white !default; $ibo-vendors-highlightjs--code--color: $common-vendors-highlightjs--code--color !default;
// Override common variables // Highlight.js stylesheets
$common-vendors-highlightjs--padding: $ibo-vendors-highlightjs--padding; /* Highlight JS */
$common-vendors-highlightjs--box-shadow: $ibo-vendors-highlightjs--box-shadow; .common-hljs-container{
$common-vendors-highlightjs--border-radius: $ibo-vendors-highlightjs--border-radius; padding: 0 !important;
$common-vendors-highlightjs--code--padding-x: $ibo-vendors-highlightjs--code--padding-x; border: none !important;
$common-vendors-highlightjs--code--padding-y: $ibo-vendors-highlightjs--code--padding-y; }
$common-vendors-highlightjs--background-color: $ibo-vendors-highlightjs--background-color; pre code.hljs {
$common-vendors-highlightjs--color: $ibo-vendors-highlightjs--color; display: block;
$common-vendors-highlightjs--keyword--color: $ibo-vendors-highlightjs--keyword--color; overflow-x: auto;
$common-vendors-highlightjs--number--color: $ibo-vendors-highlightjs--number--color; padding: $ibo-vendors-highlightjs--padding !important;
$common-vendors-highlightjs--attribute--color: $ibo-vendors-highlightjs--attribute--color; }
$common-vendors-highlightjs--regexp--color: $ibo-vendors-highlightjs--regexp--color;
$common-vendors-highlightjs--meta--color: $ibo-vendors-highlightjs--meta--color; code.hljs {
$common-vendors-highlightjs--tag--color: $ibo-vendors-highlightjs--tag--color; padding: $ibo-vendors-highlightjs--code--padding-y $ibo-vendors-highlightjs--code--padding-x !important;
$common-vendors-highlightjs--string--color: $ibo-vendors-highlightjs--string--color; }
$common-vendors-highlightjs--comment--color: $ibo-vendors-highlightjs--comment--color; /**
$common-vendors-highlightjs--selector-class--color: $ibo-vendors-highlightjs--selector-class--color; * Obsidian style
$common-vendors-highlightjs--code--color: $ibo-vendors-highlightjs--code--color; * ported by Alexander Marenin (http://github.com/ioncreature)
*/
.hljs {
box-shadow: $ibo-vendors-highlightjs--box-shadow !important;
border-radius: $ibo-vendors-highlightjs--border-radius !important;
white-space: pre-wrap;
border: none !important;
color: $ibo-vendors-highlightjs--color !important;
background: $ibo-vendors-highlightjs--background-color !important;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-selector-id {
color: $ibo-vendors-highlightjs--keyword--color !important;
}
.hljs-number {
color: $ibo-vendors-highlightjs--number--color !important;
}
.hljs-attribute {
color: $ibo-vendors-highlightjs--attribute--color
}
.hljs-regexp,
.hljs-link {
color: $ibo-vendors-highlightjs--regexp--color !important;
}
.hljs-meta {
color: $ibo-vendors-highlightjs--meta--color !important;
}
.hljs-tag,
.hljs-name,
.hljs-bullet,
.hljs-subst,
.hljs-emphasis,
.hljs-type,
.hljs-built_in,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: $ibo-vendors-highlightjs--tag--color !important;
}
.hljs-string,
.hljs-symbol {
color: $ibo-vendors-highlightjs--string--color !important;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion {
color: $ibo-vendors-highlightjs--comment--color !important;
}
.hljs-selector-class {
color: $ibo-vendors-highlightjs--selector-class--color !important;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-name,
.hljs-strong {
font-weight: bold
}
.hljs-code,
.hljs-title.class_,
.hljs-class .hljs-title,
.hljs-section {
color: $ibo-vendors-highlightjs--code--color !important;
}

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

View File

@@ -1,4 +1,4 @@
/*! /*
* @copyright Copyright (C) 2010-2024 Combodo SAS * @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */

5
css/c3.min.css vendored
View File

@@ -1,5 +0,0 @@
/*
* @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}

108
css/common/README.md Normal file
View File

@@ -0,0 +1,108 @@
# Description
This is a brief description of how the common theme is structured using both BEM and SASS 7-1 systems and how to use them.
* [7-1 pattern](#7-1-pattern)
* [File structure](#file-structure)
* [Usage](#usage)
* [BEM methodology](#bem-methodology)
* [Principles](#principles)
* [Examples](#examples)
# 7-1 pattern
## File structure
SCSS files are structured following the [7-1 pattern](https://sass-guidelin.es/#the-7-1-pattern). \
@rveitch made a great summary with the following, which can also be found [here](https://gist.github.com/rveitch/84cea9650092119527bc).
_Note: Folders with an * are customizations we made to the original 7-1 pattern to best fit our needs_
```
css/common/
|
| utils/
| | variables/ # Sass Variables used in Functions, Mixins, Helpers, ...
| | |- colors/
| | | |- _base.scss
| | | |- _base-palette.scss # Base colors used everywhere
| | | |- _lifecycle-palette.scss # Colors used for lifecycle of an object (e.g. representing states such as new, frozen, done, ...), based on the base colors
| | | |- _semantic-palette.scss # Colors used for semantic meaning (e.g. red for errors, green for success, ...), based on the base colors
| | | ...
| | |
| | |- _depression.scss
| | |- _elevation.scss
| | |- _size.scss # Base sizes used everywhere (spacings, ...)
| | |- _spacing.scss
| | |- _typography.scss # Typography sizes, weights, families, ...
| | ...
| |
| | functions/ # Sass Functions
| | |- _color.scss # Color manipulation functions
| |
| | mixins/ # Sass Mixins
| | helpers/ # Class & placeholders helpers
|
| vendors/ # Third-party libs, should be either:
| # - Overload of the lib SCSS variables (BEST way, but possible only if the lib exposes them. e.g. Bulma)
| # - Overload of the lib necessary CSS classes only (not great as it duplicates some rules in the browser, which add weight and computation. e.g. dataTables)
| # - Duplicate the lib CSS completly to insert SCSS variables (not great as it will be outdated when updating the lib itself. e.g. jQuery UI)
| | _bulma-variables-overload.scss # Bulma CSS framework
| | _jquery-ui.scss # jQuery UI
| ... # Etc…
|
| base/
| | _reset.scss # Reset/normalize
| | _typography.scss # Typography fonts imports
| ... # Etc…
|
|- _shame.scss # Shame file, should contain all the ugly hacks (https://sass-guidelin.es/#shame-file)
` main.scss # Main Sass file
```
## Usage
To avoid common errors, files should be imported in the final file in the following order. Again those are just following the SASS guidelines:
- Utils
- Variables
- Functions
- Mixins
- Helpers
- Vendors
- Base
- Shame file
# BEM methodology
## Principles
[BEM is a methodology](https://getbem.com/) that helps you to create reusable components and code sharing in frontend development. \
The main idea is to use discriminant classes instead of nested basic selectors for 2 main reasons:
* It's easier to understand the purpose of a specific class when seeing it in the HTML markup of the SCSS file
* It's easier to override a specific class when needed as you don't need to use a selector at least as precise/complex as the one you want to override
In our implementation, we start with the code of the UI block, followed by the sub-element, then the property or modifier. Separation is made of `--` instead of `__`.
## Examples
### Classes and CSS properties example
```scss
// SCSS variables:
// - For CSS properties: CSS class, followed by CSS property
$common-button--padding-y: 6px !default;
$common-button--padding-x: 9px !default;
$common-button--border: 0 !default;
$common-button--border-radius: $common-border-radius-400 !default;
$common-button--box-shadow-bottom: 0px 2px 0px !default;
$common-button--box-shadow-top: inset 0px 2px 0px !default;
$common-button--label--margin-left: $common-spacing-200 !default;
```
### States example
```scss
// SCSS variables:
// Same rule as before, but with a `--is-` or `--on--` suffix
$common-quick-create--input--padding: $common-spacing-0 default;
$common-quick-create--input--padding-x--is-opened: $common-spacing-300 !default;
$common-quick-create--input--padding-y--is-opened: $common-spacing-300 !default;
$common-quick-create--input--width: $common-size-0 !default;
$common-quick-create--input--width--is-opened: 245px !default;
$common-quick-create--input--background-color: $common-color-white-100 !default;
$common-quick-create--input--background-color--on-hover: $common-color-grey-200 !default;
```

40
css/common/_shame.scss Normal file
View File

@@ -0,0 +1,40 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
// ==========================================================================
// $Shame
// @see http://csswizardry.com/2013/04/shame-css/
// Thanks https://github.com/heroheman/shepherd/blob/master/sass/_shame.scss
// ==========================================================================
//
// ==========================================================================
// because hacks happen.
//
// be very specific about what each piece of code is doing, and
// how to better fix it later
// ==========================================================================
//
// Try: $ git blame _shame.scss
//
// Rules:
// ---------------
// 1. If its a hack, it goes in _shame.scss.
// 2. Document all hacks fully:
// 3. What part of the codebase does it relate to?
// 4. Why was this needed?
// 5. How does this fix it?
// 6. How might you fix it properly, given more time?
// 7. Do not blame the developer; if they explained why they had to do it then their reasons are probably (hopefully) valid.
// 8. Try and clean _shame.scss up when you have some down time.
// Example:
// ---------------
// Nav specificity fix.
//
// Someone used an ID in the header code (`#header a{}`) which trumps the
// nav selectors (`.site-nav a{}`). Use !important to override it until I
// have time to refactor the header stuff.
//
// .site-nav a { color:#BADA55!important; }

View File

@@ -0,0 +1,7 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
@import "base";
@import "typography";

View File

@@ -0,0 +1,17 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$common-scrollbar--scrollbar-width: 8px !default;
$common-scrollbar--scrollbar-height: $common-scrollbar--scrollbar-width !default; /* For horizontal scrollbars */
$common-scrollbar--scrollbar-track-background-color: $common-color-transparent !default;
$common-scrollbar--scrollbar-track-border-radius: $common-border-radius-500 !default;
$common-scrollbar--scrollbar-thumb-background-color: $common-color-grey-300 !default;
$common-scrollbar--scrollbar-thumb-border: none !default;
$common-scrollbar--scrollbar-thumb-border-radius: $common-border-radius-500 !default;
$common-svg-illustration--fill: $common-color-primary-500 !default;
$common-content-block--background-color: $common-color-white-100 !default;
$common-content-block--border: 1px solid $common-color-grey-400 !default;

View File

@@ -0,0 +1,150 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/* This is an overload of the default lib. stylesheet to use local fonts instead of the CDN */
@font-face {
font-family: Raleway;
font-weight: 100;
font-style: normal;
font-display: swap;
src: local('Raleway Thin'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-100-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 100;
font-style: italic;
font-display: swap;
src: local('Raleway Thin'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-100-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 200;
font-style: normal;
font-display: swap;
src: local('Raleway ExtraLight'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-200-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 200;
font-style: italic;
font-display: swap;
src: local('Raleway ExtraLight'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-200-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 300;
font-style: normal;
font-display: swap;
src: local('Raleway Light'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-300-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 300;
font-style: italic;
font-display: swap;
src: local('Raleway Light'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-300-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 400;
font-style: normal;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-400-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 400;
font-style: italic;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-400-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 500;
font-style: normal;
font-display: swap;
src: local('Raleway Medium'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-500-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 500;
font-style: italic;
font-display: swap;
src: local('Raleway Medium'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-500-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 600;
font-style: normal;
font-display: swap;
src: local('Raleway SemiBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-600-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 600;
font-style: italic;
font-display: swap;
src: local('Raleway SemiBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-600-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 700;
font-style: normal;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-700-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 700;
font-style: italic;
font-display: swap;
src: local('Raleway'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-700-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 800;
font-style: normal;
font-display: swap;
src: local('Raleway ExtraBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-800-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 800;
font-style: italic;
font-display: swap;
src: local('Raleway ExtraBold'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-800-italic.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 900;
font-style: normal;
font-display: swap;
src: local('Raleway Black'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-900-normal.woff') format('woff'),
}
@font-face {
font-family: Raleway;
font-weight: 900;
font-style: italic;
font-display: swap;
src: local('Raleway Black'),
url($approot-relative + 'node_modules/@fontsource/raleway/files/raleway-all-900-italic.woff') format('woff'),
}

4
css/common/main.scss Normal file
View File

@@ -0,0 +1,4 @@
@import "utils/all";
@import "vendors/all";
@import "base/all";
@import "shame";

View File

@@ -0,0 +1,9 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
@import "variables/all";
@import "functions/all";
@import "mixins/all";
@import "helpers/all";

View File

@@ -0,0 +1,6 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
@import "color";

View File

@@ -0,0 +1,34 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Adjust the lightness of $sColor to the absolute $fTargetLightness value.
* It is different than lighten() / darken() that shift the current lightness by X%
*
* @return Modified color value in HSLA format
*/
@function common-adjust-lightness($sColor, $fTargetLightness) {
$iHue: hue($sColor);
$fSaturation: saturation($sColor);
$fLightness: lightness($sColor);
$fAlpha: alpha($sColor);
@return hsla($iHue, $fSaturation, $fTargetLightness, $fAlpha);
}
/**
* Adjust the alpha chanel (opacity) of $sColor to the absolute $fTargetAlpha value.
* It is different than opacify() / transparentize() that shift the current alpha value by X%
*
* @return Modified color value in HSLA format
*/
@function common-adjust-alpha($sColor, $fTargetAlpha) {
$iHue: hue($sColor);
$fSaturation: saturation($sColor);
$fLightness: lightness($sColor);
$fAlpha: alpha($sColor);
@return hsla($iHue, $fSaturation, $fLightness, $fTargetAlpha);
}

View File

@@ -0,0 +1,15 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
@import "border-radius";
@import "color";
@import "class-icon";
@import "depression";
@import "elevation";
@import "font-icon";
@import "sticky-header";
@import "text-decoration";
@import "text-position";
@import "typography";

View File

@@ -0,0 +1,26 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
%common-border-radius-100{
border-radius: $common-border-radius-100;
}
%common-border-radius-300{
border-radius: $common-border-radius-300;
}
%common-border-radius-400{
border-radius: $common-border-radius-400;
}
%common-border-radius-500{
border-radius: $common-border-radius-500;
}
%common-border-radius-700{
border-radius: $common-border-radius-700;
}
%common-border-radius-900{
border-radius: $common-border-radius-900;
}
%common-border-radius-full{
border-radius: $common-border-radius-full;
}

View File

@@ -0,0 +1,8 @@
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
$common-class-icon--small--size: 32px !default;
$common-class-icon--medium--size: 48px !default;
$common-class-icon--large--size: 64px !default;

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