Compare commits

...

804 Commits

Author SHA1 Message Date
Dolibot
b31f16c18f PHPStan > Update baseline 2025-11-29 12:09:23 +00:00
Laurent Destailleur
6af8022be1 Merge pull request #36460 from Hystepik/fix-webhook-history-on-error
Fix webhook history record save on error
2025-11-29 11:30:18 +01:00
Laurent Destailleur
c62ba31c50 Merge pull request #36433 from mdeweerd/fix/public_const
Qual: Update PHP-CS-Fixer configuration and DolibarrModules class
2025-11-28 23:34:42 +01:00
Laurent Destailleur
65fe121acf Merge pull request #36437 from aspangaro/23_accpicto2
UX Accountancy - Ledger - Add icon for more comprehension
2025-11-28 23:33:06 +01:00
Laurent Destailleur
45e4c29e25 Merge pull request #36439 from frederic34/patch-8
fix warning in upgrade2.php
2025-11-28 23:31:12 +01:00
Laurent Destailleur
e4e5af0adf Merge pull request #36442 from frederic34/patch-11
add modulepart for direct print capabilities
2025-11-28 23:30:22 +01:00
Laurent Destailleur
27161bd309 Merge pull request #36450 from mdeweerd/phpstan/dol_sort_array
Qual: Improve type hinting for phpstan in dol_sort_array()
2025-11-28 23:18:26 +01:00
Laurent Destailleur
682f00dd00 Merge pull request #36451 from Steph501/fix/emailcollector-subject-exclusion-filter
Fix: Email Collector subject/body exclusion filters not working
2025-11-28 23:15:26 +01:00
Laurent Destailleur
b839599f25 Merge pull request #36468 from frederic34/missing_specialcode
missing db migration
2025-11-28 22:54:11 +01:00
Frédéric France
16f47cd9ae Merge remote-tracking branch 'upstream/develop' into patch-11 2025-11-28 20:45:05 +01:00
Frédéric France
65af9e2591 add more 2025-11-28 20:44:34 +01:00
Frédéric France
b39eb2bc9e add more 2025-11-28 20:43:17 +01:00
Frédéric France
d7597d72d2 add more 2025-11-28 20:39:32 +01:00
Frédéric France
15124c1bf3 add more 2025-11-28 20:10:00 +01:00
Frédéric France
2afb048dfb add more 2025-11-28 19:57:10 +01:00
Frédéric France
4a42d5d8bc add more 2025-11-28 19:52:10 +01:00
Frédéric France
123af65139 add more 2025-11-28 19:42:56 +01:00
Frédéric France
8ba7fca18a fix missing migration 2025-11-28 18:55:29 +01:00
Frédéric France
c8cffbc3b5 fix missing migration 2025-11-28 18:53:03 +01:00
Lucas Marcouiller
03cdf34cea Merge branch 'develop' into fix-webhook-history-on-error 2025-11-28 16:49:05 +01:00
Laurent Destailleur
30659bfadc Merge pull request #36459 from vold-lu/api_supplier_discounts
NEW : Third Parties API can get supplier fixed discounts
2025-11-28 16:24:10 +01:00
Lucas Marcouiller
e6fa97f3ad Merge branch 'fix-webhook-history-on-error' of github.com:Hystepik/dolibarr into fix-webhook-history-on-error 2025-11-28 16:21:12 +01:00
Lucas Marcouiller
0ce80ab5e6 fix CI 2025-11-28 16:20:55 +01:00
Frédéric FRANCE
3c3345abdd Merge remote-tracking branch 'upstream/develop' into patch-11 2025-11-28 16:19:59 +01:00
Laurent Destailleur
0d5c63e6d4 Merge pull request #36455 from Hystepik/fix-prevent-use-of-trace-method
Fix prevent use of TRACE REQUEST_METHOD in waf
2025-11-28 16:19:52 +01:00
Laurent Destailleur
dd68602e31 Merge pull request #36458 from altairisfr/fix_shipment_with_origin
FIX: shipment with origin
2025-11-28 16:18:26 +01:00
Lucas Marcouiller
941606a48a Merge branch 'develop' into fix-webhook-history-on-error 2025-11-28 16:05:14 +01:00
Lucas Marcouiller
165d047bf6 Fix webhook history record save on error 2025-11-28 16:02:55 +01:00
Laurent Destailleur
3616b229bb CSS 2025-11-28 16:00:36 +01:00
Rémi Champlon
e3fbe0943e fix space 2025-11-28 15:40:57 +01:00
Frédéric FRANCE
991b867047 add another 2025-11-28 15:26:10 +01:00
Rémi Champlon
7ffb16abef fix space 2025-11-28 15:25:15 +01:00
Frédéric FRANCE
e6f9529364 Merge remote-tracking branch 'upstream/develop' into patch-11 2025-11-28 15:15:56 +01:00
Rémi Champlon
d43e697a10 implem 2025-11-28 15:14:29 +01:00
Frédéric FRANCE
cb4ed97867 Merge remote-tracking branch 'origin/patch-11' into patch-11 2025-11-28 15:09:21 +01:00
Frédéric FRANCE
1807269202 add another 2025-11-28 15:05:13 +01:00
Alexandre SPANGARO
9e993b8126 Merge branch 'develop' into 23_accpicto2 2025-11-28 14:58:27 +01:00
Mélina JOUM
206e636756 FIX: reinstate shipment with origin 2025-11-28 14:41:53 +01:00
Lucas Marcouiller
621da6eb0d Fix prevent use of TRACE method in waf 2025-11-28 11:19:16 +01:00
Laurent Destailleur
66d79d69af Doc 2025-11-28 10:28:25 +01:00
Laurent Destailleur
65c199fbf1 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-28 09:44:45 +01:00
Laurent Destailleur
6c54e4792b CSS 2025-11-28 09:17:34 +01:00
Laurent Destailleur
cd5e0b7e9d Doc 2025-11-28 09:05:14 +01:00
Laurent Destailleur
09aca511e8 Debug v23 2025-11-28 08:55:11 +01:00
Frédéric FRANCE
87fbbce618 Update upgrade2.php 2025-11-28 07:59:10 +01:00
MDW
b362b6d395 Qual: Add types for $workflow and $workflowcodes. 2025-11-28 03:14:15 +01:00
MDW
05c32bb12d Qual: Cast label to string to ensure type consistency (phpstan) 2025-11-28 02:23:46 +01:00
MDW
19637c1996 qual: Update type hints and casting in select_juridicalstatus method
- Changed type hint for $arraydata
- Added explicit casting for `code` and `country_code` in the array assignment
2025-11-28 02:23:40 +01:00
MDW
44acb8eb47 qual: Add type hint for group_list array
Add a type hint for the $group_list array for phpstan.
2025-11-28 02:23:33 +01:00
MDW
04ec188cb6 fix: Improve type casting and array initialization in user.class.php
- Added explicit type casting for array values
- Improved array initialization syntax for better readability and maintainability
2025-11-28 02:19:12 +01:00
MDW
b37aa3d1c6 Qual: Type casting in select_country and loadCacheInputReason methods 2025-11-28 02:19:05 +01:00
MDW
5117e09959 Qual: Cast properties to string in get_full_arbo method 2025-11-28 02:18:59 +01:00
MDW
55b6364bf6 Qual: Change array assignment for phpstan type deduction 2025-11-28 02:18:53 +01:00
MDW
e68b0f23d4 Qual: Change array assignment for phpstan type deduction 2025-11-28 02:18:46 +01:00
MDW
bacfd43079 qual: Add type hint for $arraydata in select_juridicalstatus method
This change adds a type hint for the $arraydata variable in the select_juridicalstatus method for phpstan
2025-11-28 02:18:40 +01:00
MDW
53baeeaf67 Qual: Improve type hinting for phpstan in dol_sort_array()
#Qual: Improve type hinting for phpstan in dol_sort_array()

- Improve phpdoc for phpstan in dol_sort_array()
2025-11-28 02:18:33 +01:00
Steph501
04bc3ee058 FIX #36447 Email Collector subject/body exclusion filters not working
The '!' prefix was removed at line 1369-1373 before being tested
at lines 1398 and 1406, causing exclusion filters to never work.

This fix uses the $not variable (already set correctly) instead of
re-testing for '!' on the modified rulevalue.
2025-11-27 23:27:36 +01:00
MDW
b33386ba0d qual: Update phpstan-baseline.neon to remove unresolvable type issues
Removed multiple entries related to unresolvable types in dol_sort_array function calls and property assignments.
2025-11-27 22:38:56 +01:00
Frédéric France
4f3e23516f add ficheuinter 2025-11-27 21:27:59 +01:00
Frédéric France
dc85a6756b add more 2025-11-27 20:55:45 +01:00
Frédéric FRANCE
9ffc224897 add project 2025-11-27 14:53:18 +01:00
Frédéric FRANCE
f757b08f97 add project 2025-11-27 14:50:14 +01:00
Frédéric FRANCE
889a716aee add modulepart for direct print capabilities 2025-11-27 12:49:00 +01:00
Laurent Destailleur
b17f37bc93 Debug v23 2025-11-27 10:47:50 +01:00
Frédéric FRANCE
57431464f5 fix warning in upgrade2.php 2025-11-27 09:30:31 +01:00
Laurent Destailleur
adae01854f Merge pull request #35552 from Easya-Solutions/develop_new_rework_webportal_lists
NEW : Rework of the webportal list for more flexibility and more templating
2025-11-27 01:33:34 +01:00
MDW
0333daa8a8 Qual: Update PHP-CS-Fixer configuration and DolibarrModules class
- Update PHP-CS-Fixer configuration to replace deprecated 'visibility_required' rule with 'modifier_keywords'
- Update DolibarrModules class to use const instead of public const for PHP 7.0 compatibility (revert recent change)
2025-11-27 01:08:46 +01:00
Laurent Destailleur
a6070c190d Merge branch 'develop' into develop_new_rework_webportal_lists 2025-11-27 00:57:48 +01:00
Laurent Destailleur
8bcf8d472a Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-27 00:55:59 +01:00
Laurent Destailleur
cd98a3a6ca Fix CI 2025-11-27 00:55:30 +01:00
Laurent Destailleur
6fd4a59b55 Merge pull request #35586 from Easya-Solutions/develop_NEW_create_ticket_mail_linked_files
NEW : when creating a ticket with linked files, send files as mail attachment to notification emails.
2025-11-27 00:37:28 +01:00
Laurent Destailleur
ef331fea2d Merge branch 'develop' into develop_new_rework_webportal_lists 2025-11-27 00:36:18 +01:00
Laurent Destailleur
32a61447a1 Merge branch 'develop' into 23_accpicto2 2025-11-27 00:23:19 +01:00
Laurent Destailleur
8ebf973745 Merge pull request #36426 from frederic34/patch-8
weight and size of shippings are float
2025-11-27 00:23:00 +01:00
Laurent Destailleur
01a6c14350 Debug v23 2025-11-27 00:21:50 +01:00
Laurent Destailleur
ce01e1d95f Debug v23 2025-11-27 00:05:04 +01:00
Laurent Destailleur
02824e8012 Merge branch 'develop' into patch-8 2025-11-26 23:41:36 +01:00
Laurent Destailleur
81ac5bddf9 Fix phpunit 2025-11-26 23:37:10 +01:00
Alexandre SPANGARO
2ee7b4be95 UX Accountancy - Ledger - Add icon for more comprehension 2025-11-26 22:36:23 +01:00
Laurent Destailleur
7071a3f5a9 Merge branch 'develop' into patch-8 2025-11-26 22:32:13 +01:00
Laurent Destailleur
b52c5a0ffa Fix CI 2025-11-26 22:31:51 +01:00
Laurent Destailleur
84e9d0bbc5 Merge branch 'develop' into patch-8 2025-11-26 22:18:36 +01:00
Laurent Destailleur
07c486ef16 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-26 22:18:11 +01:00
Laurent Destailleur
ac7c98a180 Fix perms 2025-11-26 22:17:45 +01:00
Laurent Destailleur
c046ddf813 Merge pull request #36425 from aspangaro/23_accpicto2
UX Accountancy - Ledger - Add icon for more comprehension
2025-11-26 22:05:44 +01:00
Laurent Destailleur
8d1320a604 Merge pull request #36424 from aspangaro/23_accpicto
UX Accountancy - Transaction - Add icon for more comprehension
2025-11-26 22:05:01 +01:00
Laurent Destailleur
945ac1aba0 Merge pull request #36423 from aspangaro/23_fixvalidation
FIX Accountancy - A validated transaction (blocked) can received new line
2025-11-26 22:04:24 +01:00
Laurent Destailleur
0c2ecb9eee Merge branch 'develop' into patch-8 2025-11-26 22:02:39 +01:00
Laurent Destailleur
0ac1fd39ef Fix CI 2025-11-26 22:00:55 +01:00
Laurent Destailleur
3f8f9752ae Merge branch 'develop' into patch-8 2025-11-26 21:50:00 +01:00
Laurent Destailleur
c295be762e Fix CI 2025-11-26 21:49:07 +01:00
Laurent Destailleur
6284de7c6a Merge branch 'develop' into patch-8 2025-11-26 21:36:07 +01:00
Laurent Destailleur
8c934a7560 Debug v23 2025-11-26 21:35:49 +01:00
Laurent Destailleur
4aa3306534 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-26 21:19:36 +01:00
Laurent Destailleur
cd01b3897e Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-26 21:18:26 +01:00
Laurent Destailleur
b85cd4c329 Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-26 21:17:30 +01:00
Laurent Destailleur
6775fa611d Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-11-26 21:16:36 +01:00
Laurent Destailleur
17ff2bea5d Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-11-26 21:16:11 +01:00
Laurent Destailleur
1002557746 Merge branch '17.0' of git@github.com:Dolibarr/dolibarr.git into 18.0 2025-11-26 21:12:58 +01:00
Laurent Destailleur
6d4708914d Deug v23 2025-11-26 21:07:41 +01:00
Laurent Destailleur
5f437d983a Debug v23 2025-11-26 19:24:25 +01:00
Laurent Destailleur
b497016e63 Fix typo in filter name 2025-11-26 17:19:38 +01:00
Frédéric FRANCE
bca2fbdf3b Merge branch 'develop' into patch-8 2025-11-26 17:00:53 +01:00
Laurent Destailleur
c26e37cd9b Fix edit color 2025-11-26 16:59:10 +01:00
Laurent Destailleur
4bf2dde21d Merge pull request #36420 from frederic34/clean_code_trigger
clean code trigger
2025-11-26 16:48:12 +01:00
Laurent Destailleur
725cc837c8 Merge pull request #36414 from hregis/fix_dev_multicompany
FIX multicompany dictionary sharing
2025-11-26 16:47:43 +01:00
Laurent Destailleur
53337fb848 Fix type 2025-11-26 15:51:44 +01:00
Laurent Destailleur
908880c82c SEC: fix IDOR attack on employee evaluation. Missing permision test 7ed0af2a13
SEC: empty commit for CI automata
2025-11-26 15:41:53 +01:00
Laurent Destailleur
95c89b6b86 Trans 2025-11-26 15:13:06 +01:00
Laurent Destailleur
27f4fef048 Solve confusion between tag of project/user and thirdparty in project
list
2025-11-26 15:04:22 +01:00
atm-florian
3608e9b102 SEC: 7ed0af2a13 2025-11-26 14:44:38 +01:00
Laurent Destailleur
5ac31bb84e css 2025-11-26 14:39:48 +01:00
Laurent Destailleur
b78e8faeab Debug v23 2025-11-26 14:16:06 +01:00
Laurent Destailleur
4b5c4f13ca Debug v23 2025-11-26 13:47:14 +01:00
Laurent Destailleur
f0f2afd7a3 Fix action type for button action Email 2025-11-26 13:41:16 +01:00
Laurent Destailleur
1d4333a1ac Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-26 13:29:33 +01:00
Laurent Destailleur
5c9bf0221c Increase print counter 2025-11-26 13:29:23 +01:00
Laurent Destailleur
9349de974d Fix: missing the increase of pos_counter_print 2025-11-26 13:14:19 +01:00
Frédéric FRANCE
2430355039 Merge remote-tracking branch 'upstream/develop' into patch-8 2025-11-26 11:28:45 +01:00
Frédéric FRANCE
a342bd7672 fix 2025-11-26 11:22:03 +01:00
Frédéric FRANCE
9dee0f2fd6 fix 2025-11-26 11:13:32 +01:00
Laurent Destailleur
baa7e5c8c6 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-26 10:58:46 +01:00
Laurent Destailleur
77e681ce81 Debug v23 2025-11-26 10:58:27 +01:00
Frédéric FRANCE
5f8729b553 weight and size are float 2025-11-26 10:56:37 +01:00
Alexandre SPANGARO
96685bf37c Language 2025-11-26 08:28:30 +01:00
Alexandre SPANGARO
1c39885581 UX Accountancy - Ledger - Add icon for more comprehension 2025-11-26 08:27:51 +01:00
Alexandre SPANGARO
9247b1f02b Fix CI 2025-11-26 08:09:05 +01:00
Alexandre SPANGARO
e3fea5ac56 UX Accountancy - Transaction - Add icon for more comprehension 2025-11-26 08:07:16 +01:00
Frédéric FRANCE
cbb9244255 Merge branch 'develop' into clean_code_trigger 2025-11-26 07:51:35 +01:00
Alexandre SPANGARO
2e9db19bed Use $object 2025-11-26 06:46:30 +01:00
Alexandre SPANGARO
a54c233130 FIX Accountancy - A validated transaction (blocked) can received new line 2025-11-26 06:41:16 +01:00
Laurent Destailleur
cf2df65231 CI 2025-11-26 02:23:18 +01:00
Laurent Destailleur
b1a50ccef1 Merge branch 'develop' into clean_code_trigger 2025-11-26 02:18:40 +01:00
Laurent Destailleur
4ad432788f Merge branch 'develop' into fix_dev_multicompany 2025-11-26 02:18:29 +01:00
Laurent Destailleur
00024048ca Fix CI 2025-11-26 02:18:14 +01:00
Laurent Destailleur
d453d4d410 Merge branch 'develop' into clean_code_trigger 2025-11-26 02:09:04 +01:00
Laurent Destailleur
19e0d9ab51 Merge branch 'develop' into fix_dev_multicompany 2025-11-26 02:07:55 +01:00
Laurent Destailleur
41d103446a Rename file 2025-11-26 02:06:26 +01:00
Laurent Destailleur
809c889251 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-26 02:03:15 +01:00
Laurent Destailleur
63ba5a3938 Merge branch 'develop' into clean_code_trigger 2025-11-26 01:59:16 +01:00
Expresion
bab874a669 Fix: update buying price during receipt (#36419)
Fix bad SQL when batch product

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-26 01:57:17 +01:00
Laurent Destailleur
a3dadbf2c5 Merge branch 'develop' into fix_dev_multicompany 2025-11-26 01:56:02 +01:00
Laurent Destailleur
1d9313200d Fix CI 2025-11-26 01:55:38 +01:00
Aksanti Bahiga tacite
1432588fa9 FIX: Resolve JS error on country change in public member form (#36422) 2025-11-26 01:50:15 +01:00
Laurent Destailleur
c976a4baef Merge branch 'develop' into fix_dev_multicompany 2025-11-26 01:47:32 +01:00
Laurent Destailleur
08125548dd Merge branch 'develop' into clean_code_trigger 2025-11-26 01:46:12 +01:00
Laurent Destailleur
ed8fc3ab30 Fix CI 2025-11-26 01:45:45 +01:00
Laurent Destailleur
0d4ec110dc Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-26 01:44:57 +01:00
Laurent Destailleur
e486d22b61 Fix CI 2025-11-26 01:43:23 +01:00
Laurent Destailleur
54cba89bc5 Fix CI 2025-11-26 01:40:45 +01:00
Laurent Destailleur
0027e0c126 Fix CI 2025-11-26 01:35:10 +01:00
Laurent Destailleur
c6d882b484 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 23:35:32 +01:00
Laurent Destailleur
10b546db1c Fix warning 2025-11-25 23:35:15 +01:00
Laurent Destailleur
fb4d1c0ecc Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 21:13:31 +01:00
Laurent Destailleur
bd5884a874 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 21:13:24 +01:00
Laurent Destailleur
749586792b Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-25 21:13:01 +01:00
Laurent Destailleur
3890968fbc Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-25 21:12:38 +01:00
Laurent Destailleur
b01bbd5c8f Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-11-25 21:09:55 +01:00
Laurent Destailleur
69ac8cebbf Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-11-25 21:09:26 +01:00
Laurent Destailleur
1e16bf5160 Merge branch '17.0' of git@github.com:Dolibarr/dolibarr.git into 18.0 2025-11-25 21:09:04 +01:00
Frédéric France
9f03147a38 Merge remote-tracking branch 'upstream/develop' into clean_code_trigger 2025-11-25 21:06:36 +01:00
Frédéric France
1da3e19bc2 clean code trigger 2025-11-25 21:05:16 +01:00
Laurent Destailleur
332efe2434 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 21:04:55 +01:00
Laurent Destailleur
cb221fa2b8 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 21:04:24 +01:00
Laurent Destailleur
5e67e15e1b Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-25 21:04:09 +01:00
Laurent Destailleur
427122ce7c Fix merge 2025-11-25 21:03:52 +01:00
Laurent Destailleur
9abb1b7211 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 21:03:02 +01:00
Laurent Destailleur
1b9dcf200a Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 21:00:30 +01:00
Laurent Destailleur
955bf9db10 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
2025-11-25 21:00:16 +01:00
Laurent Destailleur
8354d0a361 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-25 20:57:53 +01:00
Laurent Destailleur
adbcf9b2d8 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-25 20:57:32 +01:00
Laurent Destailleur
e920456149 Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-25 20:57:22 +01:00
Laurent Destailleur
c77220da52 Doc 2025-11-25 20:42:28 +01:00
Laurent Destailleur
3218e19091 Debug v23 2025-11-25 19:51:09 +01:00
Laurent Destailleur
6d42410dac Debug v23 2025-11-25 19:39:21 +01:00
Regis Houssin
e4070aeb97 FIX avoid php warnings (or not ?) (#36411)
* FIX avoid php warnings (or not ?)

* FIX wrong check
2025-11-25 18:52:45 +01:00
Laurent Destailleur
9b0fd0ec5c Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 18:30:42 +01:00
Laurent Destailleur
c5c0b85498 Debug v23 2025-11-25 18:18:02 +01:00
Jon Bendtsen
5044b3a102 Qual: Undefined variable $errormessage in /var/www/html/core/customreports.php on line 951 (#36392)
* checking if variable is set before testing the contents

* more PHP warnings fixes detected during #35096

* using the fixed set above

* backport eldy's fix

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-25 17:40:07 +01:00
Regis Houssin
8621eb21fa FIX multicompany dictionary sharing 2025-11-25 14:58:33 +01:00
Regis Houssin
1e484dda55 NEW webportal member authentication only with WEBPORTAL_LOGIN_BY_MEMBER_ACCOUNT (#36259)
* NEW webportal member authentication only

* FIX missing translation

* FIX php-stan errors

* FIX php-stan : cryptType is always "auto" !

* FIX remove CrypType

* FIX php-stan error

* FIX phan error

* FIX CI versions

* FIX remove wrong fix

* FIX pre-commit error

* FIX phan error

* FIX php-stan error

* FIX avoid php warning

* FIXME this check is not valid
2025-11-25 14:39:30 +01:00
Jon Bendtsen
280ca20600 more API endpoints checks multicompany auth with the same error message (#36409)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-25 14:32:28 +01:00
Charlène Benke
712da5b172 NEW : api setup - Add dictionnary holiday lists (#36402)
* Add methods to retrieve holiday and public holiday lists

* Fix SQL query formatting in api_setup.class.php

* Add user permission checks for API access

Added permission checks for user access rights before fetching data for expense reports, holidays, and HR public holidays.
2025-11-25 14:21:58 +01:00
Alexandre SPANGARO
d9b8abe3e4 FIX #36310 Accountancy - Data - Wrong account labels (cache) on write bookkeeping action (#36410)
* FIX #36310 Accountancy - Data - Wrong account labels (cache) on writebookkeeping action (#36379)

* Fix
2025-11-25 14:20:05 +01:00
Florian Mortgat
7f27552a95 FIX: empty origin type passed to addline when creating invoices from expeditions using massaction (confirm_createbills) (#36413) 2025-11-25 14:18:12 +01:00
Jakub Stříbrný
244b6f0473 FIX do not force rowid to int (#36412)
* do not force rowid to int

* Update commonobject.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-25 14:16:13 +01:00
Jakub Stříbrný
d24b8b6221 FIX do not force rowid to int (#36412)
* do not force rowid to int

* Update commonobject.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-25 14:15:36 +01:00
Jakub Stříbrný
5377df3ba7 FIX do not force rowid to int (#36412)
* do not force rowid to int

* Update commonobject.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-25 14:14:58 +01:00
Laurent Destailleur
b739a69741 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-25 12:17:05 +01:00
Laurent Destailleur
2580d0dd7f Fix missing email 2025-11-25 12:16:55 +01:00
Laurent Destailleur
2fb94f3d18 Doc 2025-11-24 20:14:20 +01:00
Jon Bendtsen
a40c97ec9c NEW: API set contact for any type in proposal, order or invoice dictionary (breaks API proposal) (#36269)
* NEW: Setting proposal contact to any in proposal contact dicitonary

* hurl tests and a little general cleanup of proposals api

* testing if the supplied type is in the dictionary

* Unique error codes

* Giving better error messages

* Making hurl tests reasonably identical for: proposals, orders and invoices

* BREAKING proposals, to make it identical with order and invoice + support for non default contacts for orders and invoices just like proposals

* adding the missing global  to order and invoice

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-24 20:12:35 +01:00
Jyhere
0ad7e52119 FIX : load_stats_commande() commande sql join (#36403) 2025-11-24 20:04:44 +01:00
Charlène Benke
3ddbcf8d9e Continue Implement new title line addition for subtotals on interventional (#36376)
* Implement new title line addition for subtotals

Added functionality to handle adding a new title line for the subtotals module, including input processing and document generation.

* Add parameters to addline method in fichinter class

* Add special_code to fichinterligne class

* Update copyright notices in commonsubtotal.class.php

Added copyright notice for Charlene Benke for 2025.

* Remove extra blank line in fichinterligne.class.php

* Change special_code to be an integer in SQL query

* Refactor intervention detail display logic

Refactor code for better readability and maintainability by removing duplicate lines and organizing the logic for displaying intervention details.

* Decode extraparams to get subtotal options

* Change default value of special_code to 0
2025-11-24 19:47:07 +01:00
Frédéric FRANCE
d2ed8fed4f can specify user timezone if no session (#36344)
* can specify user timezone if no session

* Update functions.lib.php

* Update functions.lib.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-24 19:43:48 +01:00
Alexandre SPANGARO
07f49f2a35 FIX #36310 Accountancy - Data - Wrong account labels (cache) on writebookkeeping action (#36379) 2025-11-24 19:36:00 +01:00
Evann DREUMONT
b6862f5f59 Add REST API support for listing template invoices (#36397) 2025-11-24 19:19:39 +01:00
Laurent Destailleur
71dc6dc1db Fix #35096 #36393 2025-11-24 19:18:31 +01:00
Regis Houssin
7d403a2fff FIX getEntity use element instead table_element (#36405) 2025-11-24 19:15:04 +01:00
Laurent Destailleur
85b03e227d Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-24 19:13:58 +01:00
Laurent Destailleur
ca80d82248 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-24 19:13:37 +01:00
Laurent Destailleur
ca1a9c9155 Complete #35096 #36393 2025-11-24 19:13:13 +01:00
Laurent Destailleur
111ba82936 Debug v23 2025-11-24 18:58:50 +01:00
Laurent Destailleur
e707544cca Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-24 18:26:03 +01:00
Laurent Destailleur
79b2056d39 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-24 18:25:41 +01:00
Laurent Destailleur
112028aa7e FIX #35096 #36393 Add minimal fields required asthe class is used by
custom reports
2025-11-24 18:24:15 +01:00
Alexandre SPANGARO
8181e2d3e2 FIX - Accountancy - In each transaction, it's possible to modify informations (Journal, date, ref) on transaction who are validated (blocked) (#36377) 2025-11-24 17:37:00 +01:00
Florian Mortgat
c2635f5242 FIX 17.0: perweek.php resets task progress to 0% when: (#36401)
* FIX 17.0: perweek.php resets task progress to 0% when:
1. the column "Declared real progress" is hidden (which means the corresponding form inputs won't be displayed)
2. and the user doesn't enter any time for that task (= leaves the input empty)

If the column is shown, the bug doesn't occur because the correct value is sent with $_POST.
If the user enters time, the bug doesn't occur because there is a GETPOSTISSET test for that case.

* Apply suggestion from @atm-florianm

variable name ($taskid vs $tmptaskid)
2025-11-24 16:32:27 +01:00
Laurent Destailleur
b61ff7d17a Devug v23 2025-11-24 16:29:21 +01:00
Laurent Destailleur
0c8581f80d Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
2025-11-24 16:23:07 +01:00
Laurent Destailleur
c096fd29e4 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-24 16:18:01 +01:00
Laurent Destailleur
d5a438ff00 Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-24 16:17:38 +01:00
Laurent Destailleur
b9e6243ec8 Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-11-24 16:16:00 +01:00
Laurent Destailleur
9394f24cf7 Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-11-24 16:15:26 +01:00
Laurent Destailleur
b1a4520059 Merge branch '17.0' of git@github.com:Dolibarr/dolibarr.git into 18.0 2025-11-24 16:10:29 +01:00
Laurent Destailleur
2935a245a3 Merge branch '16.0' of git@github.com:/Dolibarr/dolibarr.git into 17.0 2025-11-24 16:07:46 +01:00
Laurent Destailleur
5589ed71b2 Merge branch '15.0' of git@github.com:Dolibarr/dolibarr.git into 16.0 2025-11-24 16:07:22 +01:00
Laurent Destailleur
32f160355b Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into 15.0 2025-11-24 16:03:52 +01:00
Regis Houssin
0aa6652005 FIX #35141 (#36390)
* FIX #35141

* FIX avoid problem with chinese language
2025-11-24 16:03:38 +01:00
Laurent Destailleur
bfa695e7c5 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-24 15:52:13 +01:00
Laurent Destailleur
6894ba851b Removed deprecated comment 2025-11-24 15:52:02 +01:00
Alexandre SPANGARO
236d45547b FIX Invoice - Problem with deposit line on Type of operation (#36378) 2025-11-24 15:08:01 +01:00
Charlène Benke
aae74dac7f fix subtotal column number displayed if margin enabled (#36383) 2025-11-24 15:07:07 +01:00
Jon Bendtsen
ff44d3ce3c fixing hurl test for api users (#36380)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-24 15:06:17 +01:00
MDW
4f5c32973f Qual: Improve type hints and cache arrays in html.form.class.php (#36384)
* Qual: Improve type hints and cache arrays in html.form.class.php

- Added detailed type hints for cache arrays
- Fixed a typo in the comment for the 'num' property
- Ensured consistent type casting for integer values in cache arrays

(fixes phpstan notices)

* Qual: Add type casting in donation modules

Following cache type improvement:
- Added type casting in donation modules
2025-11-24 15:05:55 +01:00
MDW
9db4c30918 Qual: Add automatic_activation property (DolibarrModules) (#36386)
* Qual: Add automatic_activation property (DolibarrModules)

- Add `automatic_activation` property to store country-specific activation reasons
- Add public to class constants (PSR-2/php-cs-fixer)

* Qual: Simplify $module_activation test in admin.lib.php

The test for $module_activation has been simplified after declaring the property in DolibarrModules.
2025-11-24 15:05:05 +01:00
MDW
287ee92cb7 Qual: Fix nullable value by cast (for phan) (#36381)
# Qual: Fix nullable value by cast (for phan)

The update method now explicitly casts the eatby and sellby fields to integers before passing them to the idate function.

Otherwise phan considers the arguments as nullable (as it can not determine the impact of dol_strlen).
2025-11-24 15:00:15 +01:00
Charlène Benke
ee261b5a66 Adjust checkbox input style in subtotal_edit.tpl.php (#36387) 2025-11-24 14:59:34 +01:00
Florian Mortgat
5a61cc9393 FIX DA027383: permissions not checked on HRM evaluation card (#36328) (#36399)
Permissions involved:
- hrm->evaluation->readall: the user can view anyone's evaluations
- hrm->evaluation->read: the user can only view their or their subordinates' evaluations
2025-11-24 14:57:20 +01:00
dependabot[bot]
a2814f3d62 Bump actions/checkout from 5 to 6 (#36394)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 14:55:54 +01:00
Laurent Destailleur
e465d748f3 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-24 13:00:49 +01:00
Laurent Destailleur
0870e00503 Debug v23 2025-11-24 13:00:38 +01:00
Florian Mortgat
7ed0af2a13 FIX DA027383: permissions not checked on HRM evaluation card (#36328)
Permissions involved:
- hrm->evaluation->readall: the user can view anyone's evaluations
- hrm->evaluation->read: the user can only view their or their subordinates' evaluations
2025-11-24 12:21:51 +01:00
Laurent Destailleur
2734f0a032 CSS 2025-11-24 09:50:31 +01:00
Laurent Destailleur
6199c5f31e CSS 2025-11-24 09:47:37 +01:00
Laurent Destailleur
1b9f546dce Debug v23 2025-11-24 01:46:27 +01:00
Laurent Destailleur
83f9d2cab7 Debug v23 2025-11-23 22:43:19 +01:00
Laurent Destailleur
70b264715f Debug v23 2025-11-23 22:31:07 +01:00
Laurent Destailleur
7af079a87f Debug v23 2025-11-23 22:18:12 +01:00
Laurent Destailleur
8a2faed41f Debug v23 2025-11-23 22:14:34 +01:00
Laurent Destailleur
9f73e65767 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-23 21:29:58 +01:00
Laurent Destailleur
c8e12d9cb9 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-23 21:29:44 +01:00
Laurent Destailleur
fffb21b741 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-23 21:10:52 +01:00
Laurent Destailleur
3ced7b6de7 CSS 2025-11-23 21:10:40 +01:00
John BOTELLA
7494d8c2d1 UIUX : Experiment Dolibarr JS context and tools - Add tool for langs (#36389)
* Add more doc and simplify hook systeme uasge

* doc

* doc

* lang tool

* lang tool

* lang tool
2025-11-23 19:11:46 +01:00
Laurent Destailleur
e35028646e Debug v23 2025-11-23 16:33:38 +01:00
Laurent Destailleur
3ab0d148b5 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-23 16:16:27 +01:00
Laurent Destailleur
53e926371b Debug v23 2025-11-23 16:15:59 +01:00
Laurent Destailleur
b00baadb79 Start beta 2025-11-23 12:27:26 +01:00
iLLixM
852f9eeb77 FIX #36368 - avoid overlaying of EPC-QR Code and payment information (#36369)
* FIX #36368 - avoid overlaying of EPC-QR Code and payment information

The position of an EPC-QR code on an invoice is adjusted based on information about payments already made.
The EPC-QR code is only displayed on invoices if a balance remains due.

* FIX #36368 - avoid overlaying of EPC-QR Code and payment information

place EPC-QR Code on left-hand side of invoice PDF

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-23 03:44:55 +01:00
Laurent Destailleur
f96905c1f0 Fix CI 2025-11-23 03:19:11 +01:00
Laurent Destailleur
6904df8a45 Fix CI 2025-11-23 03:05:28 +01:00
Jon Bendtsen
78f90982c4 Fix: API users/groups + fix hurl tests for those (#36337)
* Fix: API users/groups + fix hurl tests for those

* we only check for the login during user creation

* restoring test/hurl/api/users/10_users.hurl from develop branch

* changing error code to 500

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-23 01:59:02 +01:00
John BOTELLA
c0c1c45680 UIUX : Experiment Dolibarr JS context and tools - More doc and simplify hook usage systeme (#36373)
* Add more doc and simplify hook systeme uasge

* doc

* doc
2025-11-23 01:54:37 +01:00
Charlène Benke
0ed2d559f8 Update directory references for product batch (#36367) 2025-11-23 01:53:51 +01:00
MDW
63a78d8c00 Qual: Add perltidy & perlcritic + updates to fix notices. (#36370)
* Qual: Add pre-commit hooks for Perl code formatting and linting

- Added perltidy hook to format Perl code
- Added perlcritic hook to lint Perl code

* Qual: Update file opening syntax in build scripts (perltidy)

The changes update the syntax for opening files in several build scripts to use the three-argument form of the `open` function, which is more secure and recommended in modern Perl practices.

* Qual: Improve file handling and add strict/warnings pragmas (perlcritic)

The changes include:
- Adding 'use strict' and 'use warnings' pragmas to enforce better coding practices
- Improving file handling by using lexical filehandles (my $IN, my $SPECFROM, etc.)
- Fixing file opening and closing operations to use proper error handling
- Updating various file operations to use the new lexical filehandles
- Fixing indentation and formatting issues in the code

* Qual: Add strict and warnings pragmas to Perl scripts (perlcritic)

The changes add 'use strict;' and 'use warnings;' pragmas
- dev/build/doxygen/dolibarr-doxygen-build.pl
- dev/build/doxygen/dolibarr-doxygen-filter.pl
- dev/build/doxygen/dolibarr-doxygen-getversion.pl
- dev/build/gource/getavatars.pl
- dev/tools/dolibarr-mysql2pgsql.pl

* Qual: Add Perl no critic pragmas (perlcritic)

- Ignore some perlcritic notices

* Qual: Improve code formatting and readability

Perltidy:

- Indentation and spacing
- Improved variable naming and alignment
- Better code organization and structure
- Enhanced readability of conditional statements and loops

These changes do not alter the functionality of the script but make it more maintainable and easier to understand.

* qual: Exclude virtualmin from perltidy and perlcritic hooks

Exclude the virtualmin directory from both perltidy and perlcritic hooks due to specific reasons mentioned in the comment. This change ensures that these hooks do not process files in the virtualmin directory.

* Qual: Add installation of perltidy and perlcritic for pre-commit workflow

This commit adds the installation of perltidy and perlcritic as part of the pre-commit hooks workflow.

* Fix: Update version detection in dolibarr-doxygen-build.pl

- Add support for detecting version from DOL_MAJOR_VERSION and DOL_MINOR_VERSION constants
- Fix undefined variable issue in version detection

* Fix: Update getavatars.pl to use HTTPS and reverse git log

- Changed the URL from HTTP to HTTPS for Gravatar
- Added `--reverse` flag to git log command to process commits in chronological order (faster)
- Updated error message to indicate .git repository instead of .git directory (+ correct test)

* fix: Correct spelling in error messages and prompts

- Fixed typo in error message for missing environment variables
- Corrected spelling in prompt for module name input
- Improved clarity in comment for target checking
2025-11-23 01:52:07 +01:00
Laurent Destailleur
8facedc1b6 Fix CI 2025-11-23 01:47:00 +01:00
Laurent Destailleur
3a40fe5d79 Fix CI 2025-11-23 01:36:54 +01:00
Laurent Destailleur
aaa5e7aeb2 Fix CI 2025-11-23 01:30:40 +01:00
Laurent Destailleur
6a23983969 Fix warning 2025-11-23 01:06:58 +01:00
Laurent Destailleur
0f6b9f5841 Fix CI 2025-11-23 01:03:54 +01:00
Jon Bendtsen
54134eb0fa Hurl checks update Friday November 21st 2025 (#36366)
* Hurl checks update Friday November 21st 2025

* Looks like someone changed how to handle the multi entity tests that I used earlier

* updating warehouse check

* same update for users api

* and for group api

* fix GUI admin/mails_template.php checks

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-22 19:49:58 +01:00
MDW
b57495f745 Qual: Update phan baseline (#36362)
* Qual: Update Phan baseline

# Qual: Update Phan baseline

- Updated Phan baseline to reflect reduced occurrences of PhanTypeMismatchProperty and PhanUndeclaredMethod
- Fixed syntax error in card.php by adding missing closing parenthesis

* Qual: Fix PhanPluginRedundantReturnComment

# Qual: Fix PhanPluginRedundantReturnComment

- Add return type description for the getmsg method.
2025-11-22 19:49:22 +01:00
Regis Houssin
9ac7851073 QUAL update dolibarr script for Virtualmin (#36371) 2025-11-22 19:48:37 +01:00
Jon Bendtsen
8cf937e82f Qual: detect malformed DOLAPIKEY when run.sh hurl tests (#36372)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-22 19:48:02 +01:00
github-actions[bot]
853c7a2c8d PHPStan > Update baseline (#36374)
Co-authored-by: Dolibot <dolibarr-bot@users.noreply.github.com>
2025-11-22 19:47:22 +01:00
Laurent Destailleur
aac48b7f01 Close TODO 2025-11-22 16:51:45 +01:00
Laurent Destailleur
89d8b553c1 Debug v23 2025-11-22 16:23:07 +01:00
Laurent Destailleur
d571285a37 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
2025-11-21 19:14:00 +01:00
Laurent Destailleur
f170d926f6 Debug v23 2025-11-21 19:12:22 +01:00
Laurent Destailleur
424484a4c3 Debug v23 2025-11-21 19:11:32 +01:00
Jacobus Gerards
8a7bfd737d Update llx_accounting_account_nl.sql (#36361)
Fix a typo in account sql for nl (otherwise this will produce a foreign key constraint error when loading the schema)

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-21 18:53:32 +01:00
John BOTELLA
7415ae1597 UIUX : Experiment Dolibarr JS context and tools - Add context variables and improve documentation. (#36360)
* Add context variables and improve documentation.

* fix hook execution and add sequential await hook

* fix hook execution and add sequential await hook

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-21 18:35:01 +01:00
iLLixM
0e8d4461c4 Fix: Prevent negative payment amount in EPC-QR Code (#36364) 2025-11-21 18:34:24 +01:00
Frédéric FRANCE
561d4deb06 clean code (#36363)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-21 18:34:09 +01:00
Frédéric FRANCE
9d4260c858 fix Ci (#36354)
* fix Ci

* Update html.form.class.php

* fix

* remove duplicate
2025-11-21 17:26:29 +01:00
Laurent Destailleur
70b3ca43da Debug v23 2025-11-21 16:17:28 +01:00
Laurent Destailleur
bb26ca6ee7 Fix makepack 2025-11-21 15:19:49 +01:00
Laurent Destailleur
b8190e137e Merge branch '22.0' of github.com:Dolibarr/dolibarr into develop 2025-11-21 15:18:08 +01:00
Laurent Destailleur
0e4bfeead7 Fix CI 2025-11-21 14:41:31 +01:00
Laurent Destailleur
1d6f8d5cbd Debug v23 2025-11-21 14:40:33 +01:00
Laurent Destailleur
705211a5f4 Doc 2025-11-21 14:35:04 +01:00
Laurent Destailleur
3e612275e8 Clean code 2025-11-21 14:25:34 +01:00
Laurent Destailleur
99d44d9cf8 spellcheck war 2025-11-21 12:38:53 +01:00
Regis Houssin
0e1ac03fb0 FIX #36347 (#36358) 2025-11-21 11:15:34 +01:00
Laurent Destailleur
7b351e1df8 Fix CI 2025-11-21 01:29:45 +01:00
Laurent Destailleur
99b656c3c2 Fix CI 2025-11-21 01:19:14 +01:00
Laurent Destailleur
839759979a Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
2025-11-21 01:15:04 +01:00
Laurent Destailleur
f68f7c3da8 Debug v23 2025-11-21 01:02:48 +01:00
Laurent Destailleur
6e6253f40d Close #36120 2025-11-21 00:16:06 +01:00
Laurent Destailleur
6dcaede8fc Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-21 00:07:49 +01:00
Laurent Destailleur
bbc100b6d3 Close #36120 2025-11-21 00:07:31 +01:00
Eric - CAP-REL
c8acd48e34 setErrors does not exists, same solution as dolibarr v19.0 (#36107)
* setErrors does not exists, same solution as dolibarr v19.0

* reload ci

* reload ci 2

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
Co-authored-by: lvessiller-opendsi <lvessiller@open-dsi.fr>
2025-11-20 23:58:15 +01:00
Jakub Stříbrný
20cf710caf NEW Add country ID resolution from country code for thirdparty api (#36345)
* NEW Add country ID resolution from country code

NEW Add country ID resolution from country code

* NEW add extrafield support when creating thirdparty via API

NEW add extrafield support when creating thirdparty via API

* Update api_thirdparties.class.php

* remove whitespace at end of line

* remove whitespaces

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 23:56:03 +01:00
John BOTELLA
243e38ba46 UIUX : Experiment Dolibarr JS context and tools - SetEventMessage Tool (#36351)
* Add new experioement tool for dolibarr context

* Add new experioement tool for dolibarr context

* fix comment

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 23:55:23 +01:00
Jakub Stříbrný
72646a4261 NEW add hook when printing new card button on thirdparty list (#36350)
to be able to use canvas on thirdparty creation

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 23:54:25 +01:00
tcesar
1875d07bb2 New Adding the possibility to import the extrafields of warehouse (#36349)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 23:52:31 +01:00
Laurent Destailleur
09da2b2365 Merge manually to close #34719. Need to add API_IN_TOKEN_TABLE=1 for the
transition to use several API tokens per user.
2025-11-20 23:51:37 +01:00
Laurent Destailleur
74eb89869e Fix globalvar 2025-11-20 22:28:38 +01:00
Laurent Destailleur
106cc684d8 Merge branch 'YannisHoareau-new-api-rest-tokens' into develop 2025-11-20 21:44:07 +01:00
Laurent Destailleur
b77e3a4cca Merge branch 'develop' into new-api-rest-tokens 2025-11-20 21:31:20 +01:00
Laurent Destailleur
d07581555a Fix travis 2025-11-20 21:13:14 +01:00
Laurent Destailleur
cf3b3f5e94 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-20 21:01:37 +01:00
Laurent Destailleur
3ea601d4c2 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-20 21:00:12 +01:00
Laurent Destailleur
bf7be58e10 Fix CI 2025-11-20 20:59:37 +01:00
Laurent Destailleur
ae3260eb0b Fix CI 2025-11-20 20:55:10 +01:00
Laurent Destailleur
342ff228d1 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-20 20:49:44 +01:00
Laurent Destailleur
f4798ee87f Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-20 20:48:14 +01:00
Laurent Destailleur
9997e8ea44 Fix CI 2025-11-20 20:41:20 +01:00
Laurent Destailleur
e43d252b91 Fix CI 2025-11-20 20:35:11 +01:00
Laurent Destailleur
c27f85d405 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-20 20:32:53 +01:00
Laurent Destailleur
1c6cc1a554 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-20 20:32:40 +01:00
Laurent Destailleur
fbe30ebfc3 Fix CI 2025-11-20 20:30:44 +01:00
Laurent Destailleur
99efd1acec Fix CI 2025-11-20 20:29:45 +01:00
Laurent Destailleur
934536a1e1 Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-20 20:28:30 +01:00
Laurent Destailleur
734ef58a2a Fix CI 2025-11-20 20:27:43 +01:00
Laurent Destailleur
ae4522c152 Fix CI 2025-11-20 20:14:52 +01:00
Josep Lluís
3f58b064c6 Update redirect location for single record found (#36352)
Update redirect location for single record found in v22. In develop version is resolved
2025-11-20 19:53:59 +01:00
Laurent Destailleur
13bcab94c5 Debug v23 2025-11-20 19:53:05 +01:00
Laurent Destailleur
a94ab3874d Close #35819 by using a new function dol_clone_in_array() 2025-11-20 19:40:57 +01:00
Laurent Destailleur
141fa57511 Debug v23 2025-11-20 17:05:34 +01:00
Laurent Destailleur
18c30daf11 Debug v23 2025-11-20 17:04:53 +01:00
Laurent Destailleur
211f215a8f Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-20 16:46:08 +01:00
Laurent Destailleur
bb8953edaa Show message only if required 2025-11-20 16:45:58 +01:00
Laurent Destailleur
5328433f0d Debug v23 2025-11-20 16:38:56 +01:00
Frédéric FRANCE
a43e7ae58c clean phpdoc (#36342)
* clean phpdoc

* Update actioncomm.class.php
2025-11-20 16:24:38 +01:00
Laurent Destailleur
c94b977000 Fix CI 2025-11-20 16:23:47 +01:00
Laurent Destailleur
52ae79095f Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-20 16:20:25 +01:00
Laurent Destailleur
41526eaabd Fix CI 2025-11-20 16:20:07 +01:00
Laurent Destailleur
0648af5e11 Fix CI 2025-11-20 16:19:06 +01:00
Charlène Benke
7d3dedbfc4 Continue to integrate subtotals on fichinter (#36325)
* add CommonSubtotal usage on fichinter class

* Add 'fichinter' to element check in subtotal_create

* Implement subtotal line addition in card.php

Added functionality to handle subtotal lines in the card.

* Update card.php

* Update permission checks for intervention module

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 16:13:56 +01:00
Laurent Destailleur
9e5043bed6 Restore view in one page without scrolling. TODO Must migrate this page
with modulebuilder.
2025-11-20 16:12:57 +01:00
Laurent Destailleur
1caeaa9827 Debug v23 2025-11-20 15:37:00 +01:00
ldestailleur
9e8460c3dc Fix CI 2025-11-20 15:17:01 +01:00
ldestailleur
70f5e20572 Fix CI 2025-11-20 15:16:04 +01:00
Laurent Destailleur
3a617ed772 Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-11-20 15:14:27 +01:00
Laurent Destailleur
f32386208d Fix CI 2025-11-20 15:14:09 +01:00
Laurent Destailleur
1adf4ce67f Fix CI 2025-11-20 15:13:52 +01:00
Laurent Destailleur
900646a848 CSS 2025-11-20 15:05:13 +01:00
Laurent Destailleur
2e52ef2552 Doc 2025-11-20 14:00:18 +01:00
Laurent Destailleur
ce6dc7edce Doc 2025-11-20 13:59:36 +01:00
Laurent Destailleur
288283bf36 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
2025-11-20 13:59:03 +01:00
Laurent Destailleur
d9e1973edb Update blockedlog 2025-11-20 13:55:48 +01:00
Regis Houssin
f1bad6fa69 QUAL update mysql workbench (#35955)
* QUAL update mysql workbench

* NEW add link to mac api rest client for test

* FIX add apple

* FIX Mister D

* FIX Brian is in the kitchen

* FIX modeste

* Revert "FIX modeste"

This reverts commit a268f6265f.

* FIX youhou
2025-11-20 12:01:41 +01:00
Laurent Destailleur
0bfd72a995 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-20 12:00:49 +01:00
Laurent Destailleur
10c0de4467 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-20 11:55:18 +01:00
Laurent Destailleur
ae131796d6 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-20 11:51:51 +01:00
Laurent Destailleur
ecda16a5f6 Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-11-20 11:48:23 +01:00
Laurent Destailleur
515a615915 Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-11-20 11:44:40 +01:00
noec764
ac4820b4cb FIX: TakePOS Missing Thirdparty Id when getting more products (#36341)
Co-authored-by: Noé <noe@scopen.fr>
2025-11-20 11:34:06 +01:00
Laurent Destailleur
cc52434fa3 Clean code 2025-11-20 11:33:26 +01:00
Laurent Destailleur
3fe6795b15 Clean code 2025-11-20 11:28:00 +01:00
Laurent Destailleur
a8ed7e50f4 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-20 11:20:10 +01:00
Laurent Destailleur
cef8905f02 Clean code 2025-11-20 11:19:49 +01:00
Alain Cis
01dcb2c4aa [NEW] Add regions for CONGO, THE DEMOCRATIC REPUBLIC OF THE;CD (#36340) 2025-11-20 11:14:35 +01:00
Jakub Stříbrný
6c842a1219 NEW Allow creating contact via api with ISO code (#36322)
* Allow creating contact via api with ISO code

Add handling for country code to country ID mapping for api.

* use dol_getIdFromCode

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 11:03:08 +01:00
MDW
2d7d492bea New: Add quiet mode to hurl test runner (#36339)
- Added `--quiet` or `-q` option to disable informational output
- Updated help message to include the new option
- Modified print functions to respect quiet mode
2025-11-20 11:01:14 +01:00
tcesar
b485556c3a FIX Concat of PDF to invoices (#36329)
* Fix Concat of PDF to invoices

* Fix Concat of PDF to invoices

* Fix Concat of PDF to invoices

---------

Co-authored-by: tcesar <tcesar@albalogic.fr>
2025-11-20 11:00:04 +01:00
tcesar
7b08aab461 FIX Concat of PDF to invoices (#36329)
* Fix Concat of PDF to invoices

* Fix Concat of PDF to invoices

* Fix Concat of PDF to invoices

---------

Co-authored-by: tcesar <tcesar@albalogic.fr>
2025-11-20 10:56:08 +01:00
Eric Seigne
f9d285c416 Merge branch '18.0' of https://github.com/Dolibarr/dolibarr into 18.0 2025-11-20 10:09:57 +01:00
Eric Seigne
f1f7ea93b0 fix assign-and-label-v18 2025-11-20 10:09:29 +01:00
lvessiller-opendsi
1f6cec841f Merge pull request #35795 from hregis/fix_18_multicompany_compatibility
FIX Multicompany compatibility with "project_task"
2025-11-20 10:03:38 +01:00
lvessiller-opendsi
4dcbd826e6 Merge pull request #35812 from Easya-Solutions/18__fix_situation_remove_from_cycle
FIX remove situation invoice from cycle
2025-11-20 10:03:02 +01:00
Eric Seigne
fd5c9b0562 update github actions for race conditions of author/reviewer 2025-11-20 09:46:59 +01:00
iLLixM
8d038f32bc FIX #33148 - partial payments are taken into account in EPC QR codes (#36338)
When generating EPC QR codes on an invoice, any partial payments already made are taken into account. The remaining balance (the value of "Remaining unpaid") is then entered as the amount in the EPC QR code.
2025-11-20 01:49:24 +01:00
Frédéric FRANCE
46d6714fe0 clean code (#36317)
* clean code

* clean code

* clean doc

* clean doc

* clean doc

* clean doc

* fix

* fix

* fix

* fix

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-20 01:47:46 +01:00
Jon Bendtsen
111dce3854 Qual: fix 2 hurl tests: Contract and Emailtemplates (#36332)
* remove hurl test that requires a contract to exist

* change emailtemplates hurl tests to work when there is debug information in the API response

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-20 01:46:55 +01:00
iLLixM
346828071f FIX #36334 - reload invoice data before pdf-creation in process of generating a new member contribution (#36335) 2025-11-20 01:46:11 +01:00
Jon Bendtsen
ff2d9e987a Qual/Fix: remove entity=2 hurl test which doesn't work (#36336)
JonSweet16:hurl jonbendtsen$ ./run.sh module

----- Run hurl test on APIs ---
::notice::1. Running tests (API,GUI,public) that do not require authentication
::notice::Using existing DOLAPIKEY.
::notice::2.a. Running API tests that do require authentication
Success api/setup/10_setup_modules.hurl (13 request(s) in 2547 ms)
--------------------------------------------------------------------------------
Executed files:    1
Executed requests: 13 (5.1/s)
Succeeded files:   1 (100.0%)
Failed files:      0 (0.0%)
Duration:          2548 ms

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-20 01:45:09 +01:00
Jon Bendtsen
d9814738e1 Qual: Fix broken hurl test for project GUI (#36333)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-20 01:44:27 +01:00
Laurent Destailleur
c3f4f02f63 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-19 21:46:00 +01:00
Laurent Destailleur
88f184bcb0 Trans 2025-11-19 21:44:34 +01:00
Laurent Destailleur
71fd5f2f62 Merge branch 'develop' into new-api-rest-tokens 2025-11-19 21:26:41 +01:00
Jon Bendtsen
50c7ccd053 Fix: test for existing DOLAPIKEY before trying to get it using username and password (#36331)
* Fix: test for existing DOLAPIKEY before trying to get it using username and password

* remove the print statement that made the API key be wrong

* writing print_info to stderr

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-19 21:03:12 +01:00
John BOTELLA
ec6219c183 UIUX : Experiment Dolibarr JS context and tools (#36327)
* UX experiment Dolibarr JS tools

* collapse help

* improuve logs
2025-11-19 19:42:00 +01:00
Regis Houssin
bd51548638 FIX avoid php warning error (#36330) 2025-11-19 19:35:02 +01:00
Jon Bendtsen
12c0f73682 Fix hurl assert for API warehouses to new reply from Dolibarr (#36274)
* Fix hurl assert for API warehouses to new reply from Dolibarr

* Asserting with jsonpath can handle if there are extra keys in the json like debug which mdeweerd experienced

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 19:34:11 +01:00
Jon Bendtsen
dfb19ddc6b New thorough Hurl tests for pages under /projet/ in Dolibarr's GUI (#36275)
* New throrough Hurl tests for pages under /projet/ in Dolibarr's GUI

* fix spelling typo

---------

Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-19 19:33:29 +01:00
Jon Bendtsen
c0bf718df3 using different hurl test to verify we are in the homescreen and that it works (#36294)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-19 19:32:37 +01:00
Frédéric FRANCE
d5e641e248 fix doc subtotal tpl (#36326)
* fix subtotal create tpl

* fix subtotal create tpl

* property errors is always set

* clean baseline
2025-11-19 19:21:19 +01:00
Florian Mortgat
c0850d9a3f FIX DA027383: permissions not checked on HRM evaluation card (#36328)
Permissions involved:
- hrm->evaluation->readall: the user can view anyone's evaluations
- hrm->evaluation->read: the user can only view their or their subordinates' evaluations
2025-11-19 19:19:55 +01:00
Laurent Destailleur
918443562e Fix warning 2025-11-19 16:25:16 +01:00
Laurent Destailleur
c1699eed56 Debug v23 2025-11-19 16:18:09 +01:00
Laurent Destailleur
7645a6dc87 Debug v23 2025-11-19 16:16:53 +01:00
Laurent Destailleur
34dc9a9cfd Debug 2025-11-19 16:07:03 +01:00
Laurent Destailleur
6c9a70ebdf CI 2025-11-19 15:52:47 +01:00
Laurent Destailleur
46fb9826d2 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-19 15:40:10 +01:00
Laurent Destailleur
3b74f64d00 Add checkmajorversion.yml 2025-11-19 15:39:59 +01:00
Charlène Benke
b45ee47907 NEW : add product_type field on fichinter (preparing subtotal) (#36196)
* NEW : add product_type field on fichinter (preparing subtotal)

Added product_type to SQL queries for fetch, insert, and update methods.
field already present on table, so let start add subtotal on interventionals

* Update fichinterligne.class.php

* Update copyright information in card-rec.php

Updated copyright year and name for Charlie Benke.

* Update fichinterligne.class.php

* Update fichinterligne.class.php

* Update fichinterligne.class.php

* Update fichinterligne.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 15:27:26 +01:00
ThomasNgr-OpenDSI
eaa05a482f Allow to view ticket linked files from public interface (#32410) 2025-11-19 15:26:59 +01:00
Laurent Destailleur
a605244dea css 2025-11-19 15:23:07 +01:00
kkhelifa-opendsi
548bb94e4f NEW: Rework of the management of the card and fields on the web portal (#36076)
* NEW: Rework of the management of the card and fields on the web portal

* Correction pre-commit check

* Correction affichage logo login

* Ajout hook

* Ajout params fonction FormWebPortal::convertAllLink()

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction phpstan

* Correction travis

* Correction travis

* Correction travis

* Correction travis

* Correction

* Fix get options of sellist by AJAX in webportal scope

* Correction pre-commit

* Correction pre-commit

* Add hook and change hook name for viewImage controller

* Correction phan

* Corrections

* Corrections
2025-11-19 15:14:53 +01:00
Charlène Benke
da77a93205 extrafields type link fail if object not internal (#36315)
without send the classpath we have an error on selectforforms function

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 14:55:37 +01:00
Günter Lukas
eb2d345330 Fix #36282: Update shipment reference handling in commondocgenerator (#36283)
* Update shipment reference handling in commondocgenerator

* Refactor order reference assignment for clarity

* Refactor origin object handling in shipment array

* Refactor origin object handling in shipment array

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 14:49:16 +01:00
Frédéric FRANCE
b449edad3a enhance reminders create (#36321)
* enhance reminders create

* enhance reminders create

* enhance reminders create

* enhance reminders create

* enhance reminders create

* clean js

* clean js

* clean js

* clean js

* clean js

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 14:47:41 +01:00
Alexandre SPANGARO
7e2f7f163d Accountancy - Resolve some problem on new function "Discount in accountancy" (#36285)
* FIX Accountancy - Discount wrong function & problem HTML injection

* FIX Accountancy - Wrong base for already / not yet function - Piece_num is not enough strong et editable

* FIX Accountancy - Discount - Use closing date rather than the invoice date

* FIX

* PHPPhan

* Update accountingjournal.class.php

* Update accountingjournal.class.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 14:43:27 +01:00
github-actions[bot]
3cd79f4497 PHPStan > Update baseline (#36305)
Co-authored-by: Dolibot <dolibarr-bot@users.noreply.github.com>
2025-11-19 14:16:21 +01:00
MDW
96e35c7a33 Fix: PhanTypeMismatchProperty error in invoice creation (#36323)
* 🐛 Fix PhanTypeMismatchProperty error in invoice creation

The error occurred due to incorrect type handling in the invoice creation process. The changes fix this by properly handling the subtype field as an integer. This ensures type consistency and prevents potential runtime errors.

* FIX: Correct assignment to linkedObjectsIds  in card.php

# FIX: Correct assignment to linkedObjectsIds  in card.php

Modified the structure of linkedObjectsIds to include the rowid as a key to match the property type.

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 14:16:00 +01:00
Laurent Destailleur
4989c9c3b1 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-19 14:09:14 +01:00
Yamil Esteban Garcia
6d5835e90f FIX Move 'holiday' from old path array to new one (#36308)
* Remove 'supplier_invoice' from old path array

* Update module path in arrayforoldpath

Sorry Eldy, I was confused. You are absolutely right, it is already corrected.

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 14:09:05 +01:00
Laurent Destailleur
56f2cdab10 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-19 14:07:56 +01:00
Laurent Destailleur
f7f0b408e2 Migrate holiday files 2025-11-19 14:06:07 +01:00
iouston
c4f1dbddbb Add product type check in line validation (#36319)
* Add product type check in line validation

needed by sous total plugins style which use line with type 9 for title, subtitle or free text. without the chek inb line validation, title, sub title or free text disappears

* Update card.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 13:17:48 +01:00
Laurent Destailleur
292b235241 Fix CI 2025-11-19 13:14:48 +01:00
Laurent Destailleur
c65e03ecb6 Fix CSS 2025-11-19 13:01:35 +01:00
Laurent Destailleur
50de292f51 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-19 12:50:45 +01:00
Laurent Destailleur
fc8cc70d7e Clean code 2025-11-19 12:50:32 +01:00
John BOTELLA
33d65c19dd Fix css login page patch 02 (#36320)
* fix css login page patch 01

* fix css login page patch 02

* fix css login page patch 02

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-19 12:40:52 +01:00
Laurent Destailleur
77e66216dc Fix ci 2025-11-19 12:15:48 +01:00
Laurent Destailleur
5ccab94697 Fix CI 2025-11-19 12:12:07 +01:00
Laurent Destailleur
0a6489a55f Fix CI 2025-11-19 11:59:33 +01:00
Laurent Destailleur
dd39b91e5a Fix ci 2025-11-19 11:40:02 +01:00
Laurent Destailleur
8a8ed7fa67 Fix CI 2025-11-19 11:28:58 +01:00
Laurent Destailleur
75d1f27730 Fix CI 2025-11-19 11:16:24 +01:00
Laurent Destailleur
37dca42aee Doc 2025-11-19 11:05:26 +01:00
MDW
45184e9741 Qual: Update phan baseline (#36318)
# Qual: Update phan baseline

Remove fixed notices from exceptions.
2025-11-19 10:58:00 +01:00
Laurent Destailleur
613a4bab2d Fix CI 2025-11-19 10:57:11 +01:00
Laurent Destailleur
d858764b15 Add config param $dolibarr_main_restrict_eval_methods with whitelist of
functionsallowed in dol_eval. Advisory GHSA-x3w7-24rq-gvc5
2025-11-19 03:44:24 +01:00
Laurent Destailleur
63cca7f128 Doc 2025-11-18 23:36:26 +01:00
Laurent Destailleur
9818c76f7f MAIN_DISALLOW_STRING_OBFUSCATION_IN_DOL_EVAL replaced with
MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL
2025-11-18 23:34:23 +01:00
Laurent Destailleur
af0fcb0c24 Doc 2025-11-18 22:51:24 +01:00
Laurent Destailleur
845514af35 Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop 2025-11-18 22:47:04 +01:00
Laurent Destailleur
947389b072 NEW Disable by default obfuscation methods and function in extrafields
evaluable strings. Can re-enable with
MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL=1
2025-11-18 22:45:56 +01:00
Marc
d9ec700a3e FIX #36306 (#36307) 2025-11-18 22:06:40 +01:00
Laurent Destailleur
bbbb958dc0 Fix CI 2025-11-18 22:03:57 +01:00
John BOTELLA
312ea7d9eb fix css login page patch 01 (#36313)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-18 22:03:49 +01:00
Laurent Destailleur
bcde1eb545 NEW Add filter on agenda event progression on agenda page 2025-11-18 21:59:47 +01:00
Laurent Destailleur
b748ffd528 Secure the dol_eval 2025-11-18 18:57:17 +01:00
John BOTELLA
b9b8fc5bbe Fix import lines (#36303) 2025-11-18 18:01:07 +01:00
Laurent Destailleur
78384eca54 Clean code 2025-11-18 17:14:42 +01:00
Laurent Destailleur
ac2fe3e991 Comment 2025-11-18 16:59:24 +01:00
Laurent Destailleur
5aaf9cd565 NEW Add hook on calcula_price() and get_default_tva() 2025-11-18 16:57:50 +01:00
Laurent Destailleur
4dd05e0199 Debug v23 2025-11-18 15:45:45 +01:00
Laurent Destailleur
235233eaf8 WIP LNE 2025-11-18 15:37:37 +01:00
kkhelifa-opendsi
e8349a97e6 Merge branch 'develop' into develop_new_rework_webportal_lists 2025-11-18 15:22:53 +01:00
Laurent Destailleur
81527a9fe9 Clean code 2025-11-18 12:03:23 +01:00
Laurent Destailleur
bba8884d13 Clean code 2025-11-18 11:48:33 +01:00
Frédéric FRANCE
8d459e469d clean code (#36260)
* clean code

* clean code

* clean code

* clean code

* fix $val might not be defined

* fix phpstan errors reported

* fix phpstan errors reported

* fix phpstan errors reported

* fix phpstan errors reported

* fix phpstan errors reported

* fix phpstan errors reported

* ignore phpstan reported for later

* clean code

* clean code

* clean code

* clean

* test
2025-11-18 11:41:28 +01:00
MDW
785753bbee Qual: Change field name to let phan warn about argument order (#36261)
* FIX wrong $param parameter position

* FIX ok it's good ! ;-)

* Qual: Change field name to let phan warn about argument order

# Qual: Change field name to let phan warn about argument order

Most of the time print_liste_field_titre() is called with $param instead of $moreparam.
By changing the argument name, phan will warn if the position is likely incorrect.

* Fix: Fix parameter order in print_liste_field_titre calls

- Fixed parameter order in print_liste_field_titre calls to maintain consistency

---------

Co-authored-by: Regis Houssin <regis.houssin@inodbox.com>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-18 11:40:32 +01:00
Florian Mortgat
8e30fc0bd1 FIX 19.0 - attachments upload dir for invoices not always determined correctly (doesn't always take multi-entity into account) (#36302) 2025-11-18 11:39:45 +01:00
Laurent Destailleur
f05f5af59e Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-18 11:38:31 +01:00
Laurent Destailleur
61a849090b Close #36298 2025-11-18 11:36:45 +01:00
Regis Houssin
2027f9c951 FIX avoid php warnings (#36301) 2025-11-18 11:31:38 +01:00
Regis Houssin
21843e68b0 FIX #36149 (#36150) 2025-11-18 10:12:05 +01:00
Laurent Destailleur
3badbe94ab Debug v23 2025-11-18 03:12:08 +01:00
Laurent Destailleur
9f555e03bd Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-18 02:52:44 +01:00
Laurent Destailleur
e96db77fda Look and feel Debug v23 2025-11-18 02:49:47 +01:00
John BOTELLA
0d1fd4b9ff New tooltip freeze from experimental to develop branch (#36266)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 22:36:21 +01:00
Frédéric FRANCE
8f52c44e5f can edit color in dict.php (#36270)
* can edit color in dict.php

* Update html.form.class.php

* Update html.form.class.php
2025-11-17 22:25:06 +01:00
William Mead
24e519c5a0 FIX QUAL intervention API close (#36278)
* Refactored close method

* Updated PHPDoc

* Updated PHPDoc

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 22:15:44 +01:00
MDW
991706e731 FIX: Fix version extraction in setup_conf.sh (#36281)
# FIX: Fix version extraction in setup_conf.sh

The version extraction regex was updated to handle both DOL_VERSION and DOL_MAJOR_VERSION constants in version.inc.php.
The version is now available as DOL_MAJOR_VERSION since 29b1e75

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 22:05:33 +01:00
MDW
c92b87dfec Qual: (commonnumrefgenerator): Add abstract method getExample (#36271)
- `getExample()`: Returns an example of the numbering format

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 22:03:08 +01:00
MDW
b2d30053b4 Qual: Enhance hurl test documentation and run script (#36291)
- Added detailed documentation for running specific tests, including options and exclusions
- Improved installation instructions with platform-specific guidance
- Enhanced error handling and user feedback
- Added support for GitHub-compatible messages
- Improved script structure and readability

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 21:52:13 +01:00
MDW
1072419141 Qual: Update pre-commit hooks (#36262)
* Qual: Update pre-commit hooks

# Qual: Update pre-commit hook

Updated several pre-commit hooks as long as the new ones are not alpha or beta versions

* Qual: Fix/ignore some shellcheck issues
2025-11-17 21:50:29 +01:00
MDW
f5d6533c5b Qual: (v22)Change field name to let phan warn about argument order (#36263)
* FIX wrong $param parameter position

* FIX ok it's good ! ;-)

* Qual: Change field name to let phan warn about argument order

# Qual: Change field name to let phan warn about argument order

Most of the time print_liste_field_titre() is called with $param instead of $moreparam.
By changing the argument name, phan will warn if the position is likely incorrect when '$param' is used - it will not warn for cases where $option or another
name is used.

---------

Co-authored-by: Regis Houssin <regis.houssin@inodbox.com>
2025-11-17 21:49:31 +01:00
Regis Houssin
309c2eff93 FIX wrong $param parameter position (#36265)
* FIX wrong $param parameter position

* FIX ok it's good ! ;-)
2025-11-17 21:48:32 +01:00
github-actions[bot]
f799113fac PHPStan > Update baseline (#36264)
Co-authored-by: Dolibot <dolibarr-bot@users.noreply.github.com>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 21:47:22 +01:00
Frédéric FRANCE
3a3785c92d Update SecurityTest.php (#36295)
* Update SecurityTest.php

* Update SecurityTest.php

* Update SecurityTest.php
2025-11-17 21:43:53 +01:00
Laurent Destailleur
e54cc9ab28 Fix phpunit 2025-11-17 21:40:36 +01:00
Laurent Destailleur
25b9782227 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-17 21:32:49 +01:00
Laurent Destailleur
bdb6c47b0b Fix CI 2025-11-17 21:32:29 +01:00
sweetcorreze
f66cb5ddd5 Update loanschedule.class.php (#36272)
Solve Error when schedule loans : "ERROR: 55000: currval of sequence "llx_payment_loan_rowid_seq" is not yet defined in this session LOCATION: currval_oid, sequence.c:884"

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-17 21:19:58 +01:00
noec764
cd984fa6c5 FIX: Object should be cloned here (#36289)
Co-authored-by: Noé <noe@scopen.fr>
2025-11-17 21:18:28 +01:00
Laurent Destailleur
278983c4e7 Fix CI 2025-11-17 21:16:46 +01:00
Frédéric FRANCE
a88f5d9d41 Update admin.lang (#36293) 2025-11-17 21:08:50 +01:00
dependabot[bot]
ea511792d3 Bump mdeweerd/logToCheckStyle from 2025.1.1 to 2025.11.2 (#36284)
Bumps [mdeweerd/logToCheckStyle](https://github.com/mdeweerd/logtocheckstyle) from 2025.1.1 to 2025.11.2.
- [Commits](https://github.com/mdeweerd/logtocheckstyle/compare/v2025.1.1...v2025.11.2)

---
updated-dependencies:
- dependency-name: mdeweerd/logToCheckStyle
  dependency-version: 2025.11.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 20:04:53 +01:00
Laurent Destailleur
a7c82c020d Fix CI 2025-11-17 20:01:07 +01:00
Laurent Destailleur
92ad672272 Fix CI 2025-11-17 19:42:38 +01:00
Laurent Destailleur
1abc87ff03 Clean code 2025-11-17 19:35:10 +01:00
Laurent Destailleur
10921598cb Simple way to trap error to Close #36292 2025-11-17 19:10:58 +01:00
Laurent Destailleur
d1f53517e6 Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop 2025-11-17 18:15:25 +01:00
Laurent Destailleur
0631cd61e0 Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop 2025-11-17 17:21:52 +01:00
Laurent Destailleur
4703344acc Debug 2025-11-17 16:50:53 +01:00
Laurent Destailleur
7b6186c137 Doc 2025-11-17 16:45:04 +01:00
Laurent Destailleur
e8e61605da Doc 2025-11-17 16:41:58 +01:00
Laurent Destailleur
68e6bedd27 The script generate_filelist_xml.php can check integrity from command
line.
2025-11-17 16:39:27 +01:00
Laurent Destailleur
e9a3b65e04 Trans 2025-11-17 15:16:00 +01:00
Laurent Destailleur
6161c491ae Trans 2025-11-17 15:10:05 +01:00
Laurent Destailleur
c0de8f6b53 Fight against optionflation. 2025-11-17 14:52:46 +01:00
Laurent Destailleur
72afda872d WIP LNE 2025-11-17 13:53:53 +01:00
Laurent Destailleur
642feb78d2 NEW Invert logic of default date in proposal/order/invoice creation:
Need option to NOT autofill instead of the opposite.
2025-11-17 10:57:06 +01:00
Laurent Destailleur
ed08d6389a Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-17 10:44:03 +01:00
Laurent Destailleur
6376f11f27 Trans tooltip 2025-11-17 10:43:08 +01:00
Laurent Destailleur
90ec9f7de2 Doc 2025-11-17 10:34:51 +01:00
Laurent Destailleur
22440127e1 Doc 2025-11-17 10:33:31 +01:00
Laurent Destailleur
1dd28e352a NEW Introduce getCurrency(). $conf is no more allowed into computed
formulae.
2025-11-17 10:29:55 +01:00
Laurent Destailleur
bb53a368fc CSS 2025-11-15 23:00:02 +01:00
atm-lucas
bdd8dc0046 NEW - Add a new API "product lots" (#36243)
* Add new API product lots

* fix precommit
2025-11-14 16:06:59 +01:00
Gigarun ingénierie
f837fb4fa8 Fix: Correct unit comparison bug in webportal document download (#36256)
The file size check was comparing bytes (from dol_filesize) directly with
kilobytes (from MAIN_SECURITY_MAXFILESIZE_DOWNLOADED config), causing false
positives that blocked downloads of small files.

Example: A 94 KB file (96678 bytes) was rejected because 96678 > 20480,
even though the limit was actually 20480 KB (20 MB).

Changes:
- Convert KB limit to bytes before comparison: $fileSizeMax * 1024
- Improve error message to display file size in KB for consistency
- Add detailed logging with both bytes and KB values

Fixes: Files under the configured limit are now correctly allowed to download
2025-11-14 16:05:18 +01:00
Laurent Destailleur
545a0f5532 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-14 16:00:08 +01:00
Laurent Destailleur
aa49882be0 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-14 15:59:50 +01:00
Regis Houssin
d028d0d81b FIX $param is the 5th parameter of print_liste_field_titre ($moreparam) (#36250)
* FIX $param is the 5th parameter of print_liste_field_titre ($moreparam)

* FIX phan error

* FIX other errors
2025-11-14 15:55:35 +01:00
Rudi Herouard
664b0acfb7 NEW Add SQL table for expensereport line extrafields support (#36251) 2025-11-14 15:53:49 +01:00
lvessiller-opendsi
30ecf80732 FIX keep user who validate proposal on update (#36257) 2025-11-14 15:53:31 +01:00
Laurent Destailleur
e57703a6b6 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-14 15:42:25 +01:00
Marc de Lima Lucio
4528a3dac0 FIX: customer invoices: bad totals because of situation progress (#36253) 2025-11-14 15:39:07 +01:00
Laurent Destailleur
fbbcb22d95 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-14 15:38:49 +01:00
Laurent Destailleur
0f57e9897c Fix CI 2025-11-14 15:38:37 +01:00
HeilDenDus
0f297eea96 add show and filter in fields public and private notes (#36255) 2025-11-14 15:36:22 +01:00
Laurent Destailleur
cb2428486f Fix label of status 2025-11-14 15:20:38 +01:00
Laurent Destailleur
dc689f1410 CSS 2025-11-14 15:14:02 +01:00
Laurent Destailleur
84db871954 Doc 2025-11-14 14:53:17 +01:00
Laurent Destailleur
2f02e7441f Prepare 22.0.3 2025-11-14 14:52:47 +01:00
Laurent Destailleur
e0c75b2f35 Prepare 22.0.3 2025-11-14 14:48:01 +01:00
Laurent Destailleur
29b1e75826 WIP LNE 2025-11-14 12:02:16 +01:00
Laurent Destailleur
db7b669d2a Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-14 11:47:27 +01:00
Laurent Destailleur
9c85cb4be4 WIP LNE 2025-11-14 11:47:05 +01:00
Lucas Marcouiller
81e5e0a3cb New import profile for leave requests (#36244)
Co-authored-by: Lucas Marcouiller <lmarcouiller@dolicloud.com>
2025-11-13 17:53:06 +01:00
github-actions[bot]
1578715f54 PHPStan > Update baseline (#36242)
Co-authored-by: Dolibot <dolibarr-bot@users.noreply.github.com>
2025-11-13 16:57:26 +01:00
Laurent Destailleur
059f272b16 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-13 16:26:56 +01:00
Frédéric FRANCE
593926125a clean code (#36241)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-13 16:26:31 +01:00
Eric - CAP-REL
189f9fc0be add gps position for files (#36240)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-13 16:26:18 +01:00
Laurent Destailleur
b2661d617a Trans 2025-11-13 16:25:53 +01:00
Laurent Destailleur
008443305a Fix CI 2025-11-13 13:22:28 +01:00
Laurent Destailleur
cb40305764 Fix CI 2025-11-13 13:12:34 +01:00
Laurent Destailleur
ed9f3ca915 Fix CI 2025-11-13 13:11:59 +01:00
Laurent Destailleur
cba1bcdb84 Fix CI 2025-11-13 13:11:30 +01:00
Laurent Destailleur
61a194f57e Fix CI 2025-11-13 13:10:32 +01:00
Laurent Destailleur
c26c4571d8 Fix CI GETPOST -> GETPOSTINT 2025-11-13 13:09:28 +01:00
Laurent Destailleur
5c353d5f0a Fix CI 2025-11-13 13:09:06 +01:00
Laurent Destailleur
b022194600 Fix CI GETPOST -> GETPOSTINT 2025-11-13 13:09:00 +01:00
Laurent Destailleur
be48f98961 Fix CI 2025-11-13 13:02:52 +01:00
Laurent Destailleur
cb6ffabc42 Fix CI 2025-11-13 13:00:55 +01:00
Laurent Destailleur
c32be1c055 Fix CI 2025-11-13 12:48:53 +01:00
Laurent Destailleur
44beed0a94 Fix CI 2025-11-13 12:44:39 +01:00
Laurent Destailleur
3bb348ba9a CSS 2025-11-13 12:39:04 +01:00
Laurent Destailleur
faa8c0dbaf Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-13 12:31:16 +01:00
Laurent Destailleur
66d6b13278 Fix warning 2025-11-13 12:31:06 +01:00
kkhelifa-opendsi
7ce308350f Merge branch 'develop' into develop_new_rework_webportal_lists 2025-11-13 12:28:03 +01:00
lvessiller-opendsi
9de04b1c48 Merge pull request #35809 from marc-dll/18.0_FIX_expensereport_bankaccount_access
FIX: expense report card: do not show bank account if user cannot see them
2025-11-13 09:39:39 +01:00
Eric - CAP-REL
7e7939d234 Merge pull request #35893 from RyAbn/18.0_FIX_Email_collector_no_msg_parts_fatal_error
FIX: Email Collector Module
2025-11-13 09:22:44 +01:00
Laurent Destailleur
6b675eeb81 Fix error reporting 2025-11-13 04:22:58 +01:00
Laurent Destailleur
557c3c5d18 Fix SQL 2025-11-13 04:22:35 +01:00
Laurent Destailleur
0ddcc03d71 Fix GETPOST 2025-11-13 03:42:29 +01:00
Laurent Destailleur
66ae002541 Fix GETPOST 2025-11-13 03:38:48 +01:00
Laurent Destailleur
957c5645e2 Fix type 2025-11-13 03:33:42 +01:00
Laurent Destailleur
f6783b35fd Fix type 2025-11-13 03:25:20 +01:00
Laurent Destailleur
9dc4f6bc5d Fix type 2025-11-13 03:25:00 +01:00
Laurent Destailleur
c4abf5d3ca Fix regression 2025-11-13 02:12:15 +01:00
Laurent Destailleur
d03ab90be2 Close #34750 by backport of code from v22 2025-11-13 00:34:23 +01:00
Laurent Destailleur
cea7734ddf Fix $$ 2025-11-13 00:18:55 +01:00
Noé Cendrier
e5480945bc FIX: Mo::deleteLine() - stock movement correction (#34733)
* FIX: Mo::deleteLine() - stock movement correction should not rely on linked lines

* FIX: do not permit product line to consume removal if product consumption started
2025-11-12 23:59:15 +01:00
Laurent Destailleur
34bd3f5755 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
2025-11-12 22:02:50 +01:00
Laurent Destailleur
8c394c70b8 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-11-12 21:56:01 +01:00
Laurent Destailleur
1affd67437 Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-12 21:54:29 +01:00
Laurent Destailleur
2db335dd0e Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-11-12 21:51:30 +01:00
Laurent Destailleur
dba065c222 Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-11-12 21:50:04 +01:00
Laurent Destailleur
29edc77dd5 Merge branch '17.0' of git@github.com:Dolibarr/dolibarr.git into 18.0 2025-11-12 21:46:53 +01:00
Laurent Destailleur
99fe044868 Merge branch '16.0' of git@github.com:/Dolibarr/dolibarr.git into 17.0 2025-11-12 21:44:49 +01:00
Laurent Destailleur
8ae27c3a5f Merge branch '15.0' of git@github.com:Dolibarr/dolibarr.git into 16.0 2025-11-12 21:44:34 +01:00
Laurent Destailleur
07db28496d Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-12 21:39:30 +01:00
Laurent Destailleur
935e21c5e1 Close #35917 2025-11-12 21:39:20 +01:00
Regis Houssin
8d2d3986f3 FIX add constant for the member photo width in web portal + avoid error (#36221) 2025-11-12 21:35:18 +01:00
Laurent Destailleur
9ec8762307 Fix CI 2025-11-12 21:33:35 +01:00
Laurent Destailleur
7fe7bfa7bb Doc 2025-11-12 19:45:09 +01:00
Laurent Destailleur
5bc299922c Debug v23 2025-11-12 19:37:19 +01:00
Marc de Lima Lucio
ba0a7fe17a FIX: categories: sql error in link extrafields targettings categories (#36236) 2025-11-12 19:09:03 +01:00
Marc de Lima Lucio
aa9d5da575 FIX: resize iban column to support encryption (#36237) 2025-11-12 19:08:13 +01:00
Laurent Destailleur
2595aa5ab8 css 2025-11-12 19:07:09 +01:00
Benjamin Chanudet
e83d3a830b FIX Select correct approver when making a leave request for someone else (#36118)
* select correct approver when creating a leave request for someone else

* Clarify comments regarding default approver logic

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-12 19:05:50 +01:00
Laurent Destailleur
48a14b26b4 Debug v23 2025-11-12 18:42:14 +01:00
Laurent Destailleur
71b25742ae css 2025-11-12 18:06:50 +01:00
Laurent Destailleur
7fe8eb0884 css 2025-11-12 17:41:18 +01:00
Laurent Destailleur
55a5f4b4a2 CSS 2025-11-12 17:40:34 +01:00
Laurent Destailleur
46839dc869 Fix trans 2025-11-12 17:35:56 +01:00
Laurent Destailleur
65024ebf63 Fix bad translation string 2025-11-12 17:34:53 +01:00
Laurent Destailleur
9c72afd95b Short version of Go back 2025-11-12 17:30:39 +01:00
Laurent Destailleur
05c624f1cd WIP 2025-11-12 17:25:40 +01:00
Laurent Destailleur
5356cd9b93 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-12 16:02:15 +01:00
Laurent Destailleur
71d129c70a Debug v23 2025-11-12 16:02:03 +01:00
Laurent Destailleur
33f771e548 Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-11-12 15:52:10 +01:00
Ryad ABANI
ea28972862 FIX: dol_escape_htmltag in extrafields_view (#36136)
Co-authored-by: Ryad ABANI <ryad.abani@scopen.fr>
2025-11-12 15:44:40 +01:00
atm-adrien
3ddf7305bd FIX : The order closing date was not filled in during the shipment validation (workflow module). (#36235) 2025-11-12 15:39:44 +01:00
Laurent Destailleur
da08b2f5c3 Update status 2025-11-12 15:39:37 +01:00
Frédéric FRANCE
2ba87e0d32 add phone mobile of target (#36234) 2025-11-12 15:33:56 +01:00
Laurent Destailleur
c5eb12393d Fix case 2025-11-12 15:33:14 +01:00
Frédéric FRANCE
8cb1af4fcb clean code (#36233)
* clean code

* Update html_cerfafr.modules.php

* Update interface_50_modEventOrganization_EventOrganization.class.php
2025-11-12 15:32:29 +01:00
Laurent Destailleur
392fb33587 Tipo 2025-11-12 15:29:42 +01:00
Laurent Destailleur
ad91cdbe48 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-12 15:04:02 +01:00
Laurent Destailleur
9e7fedfec5 Debug v23 2025-11-12 15:03:31 +01:00
Laurent Destailleur
ad165e3712 Clean permissions 2025-11-12 12:55:21 +01:00
Maxime Kohlhaas
bd2183ac7c New : action to clone ticket (#36231) 2025-11-12 11:02:12 +01:00
Frédéric FRANCE
96707ab431 clean code (#36230) 2025-11-12 10:03:39 +01:00
Frédéric FRANCE
06c4c9e8b7 check access doc for massfilesarea_stock (#36229) 2025-11-12 10:03:14 +01:00
Charlène Benke
fb92ebb4e7 Implement setCategories method in task class (#36218)
Added setCategories method to manage task categories.

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-12 09:49:45 +01:00
Frédéric FRANCE
d07e8c03a0 avoid changing object after call (#36159)
* avoid changing object after call

* avoid changing object after call

* avoid changing object after call

* avoid changing object after call

* avoid changing object after call

* avoid changing object after call

* avoid changing object after call

* clean code

* clean code

* clean code

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* clean code

* clean

* clean

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-12 09:44:39 +01:00
Frédéric FRANCE
feccc7d4f5 Update header_login.tpl.php (#36220)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-12 09:39:55 +01:00
Charlène Benke
b4a01b3f63 harmonize fields orders between holiday and expensereport (#36222)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-12 09:39:39 +01:00
PierrickV
6e3fabeeab Fix typo in DLLMissing message for MyGerman.isl (#36223)
* Fix typo in DLLMissing message for MyGerman.isl

Typos:
- s/Mcrsoft/Microsoft/g
- s/credist_x86.exe/vc_redist.x86.exe/g
- dl link

* Fix DLLMissing message link for Visual C++ Redistributable

Updated the link for the Microsoft Visual C++ Redistributable installation instructions.

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-12 09:38:55 +01:00
Regis Houssin
2ea3c1bc21 FIX conflict between $user->id and $object->id (#36225)
* FIX conflict between $user->id and $object->id

* FIX better fix

* FIX arfff
2025-11-12 09:38:06 +01:00
Frédéric FRANCE
43c15cb1b9 clean code (#36228) 2025-11-12 09:36:57 +01:00
Frédéric FRANCE
e6e65d4989 Update commondocgenerator.class.php (#36227) 2025-11-12 09:36:40 +01:00
Laurent Destailleur
f0cd8d4281 Fix autogenerate login 2025-11-11 21:59:31 +01:00
Laurent Destailleur
540e5effac Responsive 2025-11-11 21:49:48 +01:00
Laurent Destailleur
2e72a9d14d Trans 2025-11-11 21:37:11 +01:00
Charlène Benke
5886abaf6f add date_c update on project_task (#36217)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-11 20:19:25 +01:00
Regis Houssin
f2e4ac5bfe FIX use $this->db instead $db (#36219)
* FIX use $this->db instead $db

* FIX use $db with static function

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-11 20:18:00 +01:00
Laurent Destailleur
3b38422977 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-11 19:52:04 +01:00
Jon Bendtsen
f2b823f6e7 Fix PHP Warning: Undefined array key "nblinesnull" in /var/www/html/projet/element.php (#36198)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-11 19:47:04 +01:00
Jon Bendtsen
d53aa65d1c NEW Add Type, Description columns to Project Overview Expense Reports (#36214)
Co-authored-by: Jon Bendtsen <xcodeauthor@jonb.dk>
2025-11-11 19:46:30 +01:00
Laurent Destailleur
548f1fdac3 Fix CI 2025-11-11 19:36:11 +01:00
Laurent Destailleur
90f00f8042 Fix CI 2025-11-11 19:36:10 +01:00
Laurent Destailleur
c07f116105 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-11-11 19:31:28 +01:00
Laurent Destailleur
554354b151 Fi CI 2025-11-11 19:31:18 +01:00
Charlène Benke
307227de53 add interventional feature on subtotal admin (#36207) 2025-11-11 19:04:19 +01:00
splohmer
b35994bf93 FIX late customer orders are not shown on start page (#36200)
due to an mismatch of the used variable in hasDelay (status) and the setted variable (statut) the late orders where never shown in the start page as the count was always wrongly zero.
2025-11-11 17:53:40 +01:00
Frédéric FRANCE
768ca25615 fix typo in interface_20_modWorkflow_WorkflowManager.class.php (#36212) 2025-11-11 17:48:50 +01:00
Francis Appels
079a55153f Fix php warning in order list (#36202)
* Fix order list php warning

* missing td
2025-11-11 17:42:03 +01:00
Francis Appels
0da7ae7bed Fix missing multiprices arraykey (#36204) 2025-11-11 17:41:44 +01:00
Laurent Destailleur
6de355b7d2 Fix error on triggers not propagated 2025-11-10 22:43:23 +01:00
Alexandre SPANGARO
c9d1179ba8 FIX Import/Export - Do not list imports or exports of Builder module backups of module descriptor files (#36192)
* FIX Import/Export - Do not list imports or exports of Builder module backups of module descriptor files

* FIX
2025-11-09 19:29:02 +01:00
Laurent Destailleur
a7ec88c2ac Fix update of color when using HTML5 2025-11-09 02:41:10 +01:00
HENRY Florian
d5a9fe97a9 FIX: when display in view mode HTML extrafeilds content doubled (#36127)
* FIX: when display in view mode HTML extrafeilds content doubled

* review

* Update extrafields_view.tpl.php

* Update extrafields_view.tpl.php

* Update extrafields_view.tpl.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2025-11-09 01:24:02 +01:00
Regis Houssin
8d63609c14 FIX missing check if partership is enabled (#36169) 2025-11-08 14:01:56 +01:00
MDW
093bbcdec2 Qual: Fix false phan positive in export.php (#36147)
* Qual: Type cast for field parameter

# Qual: Type cast for field parameter

Cast to string to ensure the value is not interpreted as a potential
array.

* Qual: Backport typing hint to fix typing in 20.0
2025-11-07 18:48:05 +01:00
Frédéric FRANCE
5fa475a074 fix directory was always overwritten (#36148) 2025-11-07 18:43:26 +01:00
Regis Houssin
3ad30f8622 FIX use array_intersect instead in_array 2025-11-07 12:07:50 +01:00
Regis Houssin
3b7cda03f3 Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into fix_18_multicompany_compatibility 2025-11-07 12:04:44 +01:00
Laurent Destailleur
25b1004c7b Fix getObjectsInCateg 2025-11-06 17:45:25 +01:00
Laurent Destailleur
583cc1f15f Fix warning 2025-11-06 17:38:36 +01:00
Kamel Khelifa
65744012a2 Correction declaration variables 2025-11-06 15:00:03 +01:00
Kamel Khelifa
9f86f70574 Ajout property in AbstractListController class 2025-11-06 14:13:22 +01:00
Kamel Khelifa
c97aee6e97 Correction phpstan 2025-11-06 12:33:41 +01:00
Kamel Khelifa
87d102417a Correction phpstan 2025-11-06 12:31:45 +01:00
Kamel Khelifa
8d88810b17 Correction phpstan 2025-11-06 12:25:03 +01:00
Kamel Khelifa
d6ad677c9c Correction phpstan 2025-11-06 11:56:56 +01:00
Kamel Khelifa
da5233547c Correction phpstan 2025-11-06 11:44:39 +01:00
Kamel Khelifa
e41ab4b17b Merge branch 'develop_new_rework_webportal_lists' of github.com:Easya-Solutions/dolibarr into develop_new_rework_webportal_lists 2025-11-06 11:20:50 +01:00
Kamel Khelifa
09d4118be2 Correction phpstan 2025-11-06 11:20:16 +01:00
kkhelifa-opendsi
5ea54ea63b Merge branch 'develop' into develop_new_rework_webportal_lists 2025-11-06 10:55:55 +01:00
Eric - CAP-REL
e5f3c2c117 Merge pull request #35963 from hregis/fix_18_wrong_hook_check
FIX wrong check of hook return
2025-11-06 09:28:56 +01:00
lvessiller-opendsi
1d24cf5ea5 Merge pull request #36027 from Easya-Solutions/18_fix_list_on_societe_price_tab
Fix listincsv on tab societe/price.php
2025-11-06 09:26:08 +01:00
Laurent Destailleur
b0e8b9650b Fix CI 2025-11-06 04:01:46 +01:00
Laurent Destailleur
484700e2d4 Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-11-06 02:31:09 +01:00
ldestailleur
027b6f060d Fix CI 2025-11-06 02:30:59 +01:00
Laurent Destailleur
689b992afb Split tasks 2025-11-05 22:40:50 +01:00
noec764
1c7cb37e74 FIX: Add missing left join to filter by extrafields (#36092)
Co-authored-by: Noé <noe@scopen.fr>
2025-11-04 18:43:20 +01:00
Florian Mortgat
a16f3bdf31 FIX 16.0: extrafield of type link to category causes SQL error in selectForFormsList() (#36074)
* FIX 16.0 (up to 19.0): extrafield of type link to category causes SQL error in selectForFormsList

* Apply suggestion from @atm-florianm
2025-11-04 13:06:58 +01:00
atm-GregM
dc7932700b Fix TICKET_ENABLE_PUBLIC_INTERFACE (#36073) 2025-11-04 12:25:57 +01:00
Kamel Khelifa
3688dd0a71 Correction list filter 2025-11-03 15:54:46 +01:00
Kamel Khelifa
fd6a397383 Correction php phan test 2025-11-03 15:49:33 +01:00
Kamel Khelifa
a4991ee551 Correction php phan test 2025-11-03 15:48:02 +01:00
Marc de Lima Lucio
223326610e FIX: expense report card: use correct bank module designator for detection 2025-10-31 13:43:21 +01:00
tnegre
2555b14f9c Fix listincsv on tab societe/price.php 2025-10-31 09:39:09 +01:00
Regis Houssin
edd4565921 FIX wrong check of hook return 2025-10-27 12:09:49 +01:00
Ryad ABANI
38980a935c FIX: Email Collector Module: manage error when imap_fetchstructure return false. Previously it generated warning and fatal error because the returned value was not of type class 2025-10-22 11:56:07 +02:00
Laurent Destailleur
20a73086e9 Merge branch 'develop' into develop_NEW_create_ticket_mail_linked_files 2025-10-21 00:05:56 +02:00
tnegre
3ce1b6bb4f NEW : On ticket creation from backend, send linked files in the email. 2025-10-20 16:08:04 +02:00
Laurent Destailleur
f99cbafd64 Merge branch 'develop' into develop_new_rework_webportal_lists 2025-10-18 12:25:14 +02:00
tnegre
66d72d0bba FIX allow a situation with credit to be removed from cycle 2025-10-17 14:13:25 +02:00
Marc de Lima Lucio
403dad1660 FIX: expense report card: do not show bank account if user cannot see them 2025-10-17 13:56:07 +02:00
Regis Houssin
12d078c651 FIXX clean code 2025-10-16 19:33:38 +02:00
Regis Houssin
0dbbd453e5 FIX Multicompany compatibility with "project_task" 2025-10-16 19:10:32 +02:00
Laurent Destailleur
40fdd49b05 Update card.php 2025-10-15 04:46:19 +02:00
Laurent Destailleur
39f84d5baa Merge branch 'develop' into new-api-rest-tokens 2025-10-15 04:38:48 +02:00
Laurent Destailleur
80e7c42e3d Update card.php 2025-10-15 04:38:25 +02:00
Laurent Destailleur
634e27d1f1 Merge branch 'develop' into new-api-rest-tokens 2025-10-15 03:41:05 +02:00
Laurent Destailleur
8e3ae42cdf Merge branch 'develop' into develop_new_rework_webportal_lists 2025-10-15 03:37:57 +02:00
Laurent Destailleur
1028ff9efe Merge branch 'develop' into develop_new_rework_webportal_lists 2025-10-01 20:04:34 +02:00
Laurent Destailleur
e230c0e0ad Merge branch 'develop' into develop_new_rework_webportal_lists 2025-10-01 20:00:10 +02:00
Kamel Khelifa
0100d37944 Correction phpstan 2025-09-29 15:32:29 +02:00
Kamel Khelifa
b567c2d011 Correction phpstan 2025-09-29 15:14:30 +02:00
Kamel Khelifa
c41602e6ec Correction phpstan 2025-09-29 14:47:45 +02:00
Kamel Khelifa
297818c775 NEW : Rework of the webportal list for more flexibility and more templating 2025-09-29 14:19:11 +02:00
Laurent Destailleur
15cedfe5de Update user.class.php 2025-08-21 01:35:40 +02:00
Laurent Destailleur
4404e8fd35 Update usergroup.class.php 2025-08-21 01:31:46 +02:00
Laurent Destailleur
afa14a9e4b Update usergroup.class.php 2025-08-21 01:29:18 +02:00
Laurent Destailleur
171ffb8f0d Update card.php 2025-08-21 01:23:16 +02:00
Laurent Destailleur
0e9cbad4f6 Update card.php 2025-08-21 00:57:57 +02:00
Laurent Destailleur
6227aac04c Update card.php 2025-08-21 00:19:44 +02:00
Laurent Destailleur
b6b34404cf Merge branch 'develop' into new-api-rest-tokens 2025-08-21 00:07:08 +02:00
Laurent Destailleur
d93184f955 Update token_list.php 2025-08-20 23:42:16 +02:00
Laurent Destailleur
8dadeddb4a Merge branch 'develop' into new-api-rest-tokens 2025-08-20 23:26:51 +02:00
Laurent Destailleur
f5e5c5c110 Update card.php 2025-08-16 04:14:17 +02:00
Laurent Destailleur
eb8868f2b2 Merge branch 'develop' into new-api-rest-tokens 2025-08-16 03:12:40 +02:00
Laurent Destailleur
8edfa3a1ab Merge branch 'develop' into new-api-rest-tokens 2025-08-16 02:44:17 +02:00
Marc de Lima Lucio
fda975970c Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-29 11:58:15 +02:00
Marc de Lima Lucio
bd89c1987f Merge branch 'develop' into new-api-rest-tokens 2025-07-28 09:22:30 +02:00
Laurent Destailleur
55da46989d Merge branch 'develop' into new-api-rest-tokens 2025-07-24 16:30:23 +02:00
Laurent Destailleur
ea9dbec6cf Merge branch 'develop' into new-api-rest-tokens 2025-07-24 11:26:20 +02:00
Laurent Destailleur
3bf263e675 Update apitoken_list.tpl.php 2025-07-15 12:54:43 +02:00
yannis
d88bf9e527 feat: remove unecessary test
permsgroupbyentitypluszero is set as an array before so cond is always
true
2025-07-10 11:29:19 +02:00
yannis
dd87b8fb9c fix: typo 2025-07-10 11:19:26 +02:00
yannis
c2f9206341 Merge branch 'new-api-rest-tokens-sql' of github.com:YannisHoareau/dolibarr into new-api-rest-tokens 2025-07-10 11:05:56 +02:00
yannis
99483364ed Merge branch 'new-api-rest-tokens-sql' of github.com:YannisHoareau/dolibarr into new-api-rest-tokens-sql 2025-07-10 11:05:11 +02:00
yannis
3e01b64543 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens-sql 2025-07-10 11:04:41 +02:00
yannis
743f699497 feat: remove unreachable code
permsgroupbyentitypluszero is set as an array before so cond is always
true
2025-07-10 11:03:43 +02:00
yannis
5806ff6887 refactor: clean code + comments 2025-07-10 10:34:04 +02:00
yannis
84a033d146 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-10 09:30:40 +02:00
yannis
88da28b5d5 feat: add comment for understanding 2025-07-09 17:27:17 +02:00
yannis
b1ba40ccbb fix: php phan 2025-07-09 17:20:51 +02:00
yannis
e9f42ce507 fix: php stan 2025-07-09 17:05:15 +02:00
yannis
b7a004372c fix: php phan 2025-07-09 16:44:21 +02:00
yannis
462c5f4d5e fix: php phan 2025-07-09 14:43:44 +02:00
yannis
185ac842d1 feat: not showing token tab if access forbidden 2025-07-09 14:21:56 +02:00
yannis
aa645d80ba fix: php phan 2025-07-09 12:05:07 +02:00
yannis
add2172540 feat: improve arrows for switching user in token card 2025-07-09 11:33:42 +02:00
yannis
be949278ff feat: cant access document of entity if different of token entity 2025-07-09 11:15:07 +02:00
yannis
641f2a9513 feat: improve permission managment 2025-07-09 09:25:57 +02:00
yannis
9617dcafd3 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-08 17:31:00 +02:00
yannis
1b346b5ed2 feat: removed unecessaty line 2025-07-08 17:25:13 +02:00
yannis
ba91e23f31 feat: correct state if it was empty (not 0) + delete 0 if adding perm 2025-07-08 17:24:20 +02:00
yannis
f039ad4052 feat: show all token for user whichever entity he uses 2025-07-08 17:03:05 +02:00
yannis
16e84d0fa9 feat: use all user perms if empty state (not if 0) 2025-07-08 16:29:46 +02:00
yannis
cdb3021ce7 feat: default state to 0 when creating a token 2025-07-08 16:23:18 +02:00
yannis
dd8c2b9c3f feat: dont defaut grant admin perms for token 2025-07-08 16:21:12 +02:00
yannis
975b35ab1e feat: avoid load of user perms if admin token + dont load user perms if state is 0 2025-07-08 16:15:47 +02:00
yannis
6206a6110c feat: not retrieving tokens if user does not use api 2025-07-08 15:55:38 +02:00
yannis
d328436786 feat: better calculation for nb user perms 2025-07-08 15:42:53 +02:00
yannis
3078c0800f feat: set 0 in state for no perms
This is because if empty state it means all current user perms so we
have to distinguish
2025-07-08 15:21:48 +02:00
yannis
61560e0101 feat: filter on user working for list of all tokens 2025-07-08 15:10:34 +02:00
yannis
f54678fc2f feat: load all user rights if token has no perms (empty state) 2025-07-08 11:45:57 +02:00
yannis
7f492d4a5e feat: update tms for postgre compatibility 2025-07-08 11:17:04 +02:00
yannis
b884f9aa67 feat: change translation 2025-07-07 17:07:39 +02:00
yannis
256eea24ea feat: add nonce for js script 2025-07-07 17:05:27 +02:00
yannis
39a6cadf11 feat: add picto for titles 2025-07-07 17:04:39 +02:00
yannis
9107c86c89 feat: Not showing API operations if use api not defined for user 2025-07-07 16:28:39 +02:00
yannis
fa3f46113a feat: change trans for understandability 2025-07-07 16:16:19 +02:00
yannis
2707e0660e feat: improve tab titles and trans 2025-07-07 16:12:24 +02:00
yannis
c24877a641 feat: add link back to list of token and to list of users 2025-07-07 15:59:42 +02:00
yannis
f211cc832d feat: added tpl for token lists 2025-07-07 15:54:52 +02:00
yannis
a118d9cb91 Merge branch 'new-api-rest-tokens-sql' of github.com:YannisHoareau/dolibarr into new-api-rest-tokens-sql 2025-07-07 14:21:40 +02:00
yannis
debd336f96 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens-sql 2025-07-07 14:20:41 +02:00
yannis
625c323f76 feat: leave state field empty 2025-07-07 14:20:24 +02:00
yannis
58c3439abb Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-07 12:17:58 +02:00
yannis
9af9bbfa3b feat: disable choosing token user for admin if creating from his list 2025-07-07 12:14:32 +02:00
yannis
366b0f231e feat: disable token filter in lists 2025-07-07 11:39:15 +02:00
yannis
2d7526a53f feat: remove unecessary url param 2025-07-07 11:06:56 +02:00
yannis
d9892a907c feat: improve display of user in admin token list 2025-07-07 10:57:12 +02:00
yannis
0cc77bb35d feat: disable token tab if api mod not enabled 2025-07-07 10:39:50 +02:00
Laurent Destailleur
fcad7d7a4b Merge branch 'develop' into new-api-rest-tokens-sql 2025-07-05 12:14:09 +03:00
yannis
d720fa80ff fix: php phan/stan 2025-07-04 16:38:02 +02:00
yannis
73ac786cbc feat: show all perms but disable button for not owned 2025-07-04 16:06:48 +02:00
yannis
8883c2e038 fix: showing bad entity 2025-07-04 14:50:07 +02:00
yannis
55fc93fdee fix: showing perms of other entity 2025-07-04 14:43:17 +02:00
yannis
fab6619cbb fix: change only tokens in related entity 2025-07-04 14:21:50 +02:00
yannis
dcd4049a9a fix: precommit 2025-07-04 11:11:46 +02:00
yannis
c2ab33cfae fix: precommit 2025-07-04 10:17:00 +02:00
yannis
18068419de fix: php phan/stan 2025-07-04 09:54:34 +02:00
yannis
3d65bb7ed6 fix: precommit 2025-07-04 09:44:32 +02:00
yannis
e6ab4caf50 fix: trans 2025-07-04 09:39:37 +02:00
yannis
37e55af4bd Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-04 09:39:12 +02:00
yannis
0dce11a4f1 feat: improve delrights that remove perms to tokens 2025-07-04 09:35:42 +02:00
yannis
7a498c0c91 feat: remove perms when removed group 2025-07-03 17:13:39 +02:00
yannis
1ffdd5736a fix: error if user had no perms (himself/group) 2025-07-03 16:03:48 +02:00
yannis
b503f10c11 feat: not erasing token perms if user stil has them (himself<->group) 2025-07-03 15:43:59 +02:00
yannis
04609c0728 feat: avoid modif on token that is not for api service 2025-07-03 14:42:43 +02:00
yannis
0d75748e01 feat: ungrant perm to tokens if lost in group 2025-07-03 14:40:44 +02:00
yannis
598cac8d99 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-03 12:18:30 +02:00
yannis
25ca6582b2 feat: ungrant perm to tokens if lost in global 2025-07-03 12:10:19 +02:00
yannis
8b4c3ef80c fix: bad test that unable to create token 2025-07-03 12:08:46 +02:00
yannis
3efe26ac47 feat: replaced sql migration file by php upgrade2 2025-07-03 11:38:33 +02:00
yannis
f0be6e458c fix: php phan/stan 2025-07-02 16:58:44 +02:00
yannis
00187b3d7c feat: auto selected user at token creation if id set 2025-07-02 15:51:24 +02:00
yannis
bb32b29c4e Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-02 15:34:58 +02:00
yannis
4c51a4309e feat: api loading rights of specified token 2025-07-02 15:22:13 +02:00
yannis
389715777e feat: improve display entity name 2025-07-02 11:21:38 +02:00
yannis
e97a1f8efd feat: encrypt/decrypt token 2025-07-02 09:20:54 +02:00
yannis
ef96314026 fix: cancel button not working when comming from admin token list 2025-07-01 16:52:26 +02:00
yannis
f7f7532665 feat: show tokens from all entities if in master entity in admin 2025-07-01 16:18:00 +02:00
yannis
ec79241dc2 feat: multicompany display for token list 2025-07-01 16:09:12 +02:00
yannis
0814fb0201 feat: multicompany display for admin token list 2025-07-01 16:04:07 +02:00
yannis
61601c43d6 feat: multicompany display for token card 2025-07-01 15:56:10 +02:00
yannis
df3e872d3a feat: disable display when multicompany is not enable 2025-07-01 14:48:53 +02:00
yannis
d57ca1f2a7 feat: mass delete from admi token list 2025-07-01 14:46:13 +02:00
yannis
74acc59da5 feat: create token for choosen user as admin 2025-07-01 14:39:27 +02:00
yannis
40f838ba58 refactor: remove useless missing translation 2025-07-01 12:15:56 +02:00
yannis
2a452876b3 refactor: clean query and add missing filter 2025-07-01 12:11:37 +02:00
yannis
79d8b9a63e feat: all users token list tab in api admin page 2025-07-01 12:03:22 +02:00
yannis
f401767cc7 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens-sql 2025-07-01 10:07:56 +02:00
yannis
833bba723c refactor: change table name in sql query for pre-commit 2025-07-01 10:06:53 +02:00
yannis
c2ef82645a feat: protection from perm in token that user don't have 2025-07-01 09:56:24 +02:00
yannis
3d9a7fa894 feat: tokens list massaction delete 2025-07-01 09:33:12 +02:00
yannis
e67d3095ed Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-07-01 09:10:41 +02:00
yannis
deea6c174e feat: check if duplicate token key 2025-06-30 17:32:13 +02:00
yannis
61e24d82fc feat: query to import old user token to new implement with perms 2025-06-30 16:49:52 +02:00
yannis
dc01e804fa feat: update fields and date format display 2025-06-27 15:46:01 +02:00
yannis
d3ac2ed53b feat: manage display of massaction buttons 2025-06-27 10:21:08 +02:00
yannis
7f3b8abdc8 feat: show back missing add button 2025-06-27 09:58:29 +02:00
yannis
dcf300b4f8 feat: multicompany managing and list improve display 2025-06-27 09:38:28 +02:00
yannis
35ecdeb9c9 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-06-27 09:13:20 +02:00
yannis
f2bdfcecdb feat: token list sort/filter/page and improvments 2025-06-26 17:04:42 +02:00
yannis
7e163656ea feat: creation form and database storage 2025-06-26 10:57:52 +02:00
yannis
526de3276a feat: disable prev/next nav in token card 2025-06-26 09:23:24 +02:00
yannis
4a1fea5e07 feat: change token modif form to only delete button 2025-06-25 17:29:05 +02:00
yannis
eece31093d feat: avoid dupe perms 2025-06-25 16:47:21 +02:00
yannis
d44aa146f4 feat: loadRights now loads rights of token if specified 2025-06-25 16:37:48 +02:00
yannis
357eaeb53f feat: change place of api tab 2025-06-25 15:22:10 +02:00
yannis
98fd331085 feat: improve list display and show numperms and not string 2025-06-25 15:17:13 +02:00
yannis
01296323d8 feat: enabling all perms will not enable unallowed global perms 2025-06-25 15:08:29 +02:00
yannis
d157ebc27b feat: auto add/delete perm if needed lower disabled 2025-06-25 14:42:42 +02:00
yannis
de1e05e618 feat: changed redirect url that was not working 2025-06-25 14:39:59 +02:00
yannis
2c7f86151d Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-06-25 12:22:51 +02:00
yannis
931121dc22 feat: only show user perms in token perms settings 2025-06-25 12:18:45 +02:00
yannis
94bf6ed9fa feat: add delete rights working 2025-06-25 11:15:53 +02:00
yannis
5404bd6b16 feat: change var names for understandability 2025-06-25 11:12:38 +02:00
yannis
d597762f18 Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-06-24 17:33:22 +02:00
yannis
fa016210de feat: add card of token in user with token permission edition 2025-06-24 17:33:02 +02:00
yannis
a6e9a9ac14 fix: unique key violated when enabling api keys for user 2025-06-24 16:38:12 +02:00
yannis
2143f303fa Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into new-api-rest-tokens 2025-06-24 12:13:40 +02:00
yannis
336a4c57e0 refactor: clean code 2025-06-24 11:40:42 +02:00
yannis
b770bd01b3 feat: added massaction option 2025-06-24 11:21:15 +02:00
yannis
42fceb4d05 feat: token list tab working 2025-06-23 16:32:34 +02:00
yannis
c46f09cac8 feat: change token to checkbox for api on user 2025-06-23 14:11:02 +02:00
806 changed files with 31073 additions and 9082 deletions

View File

@@ -18,7 +18,7 @@ jobs:
contents: read
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache

View File

@@ -0,0 +1,29 @@
---
# This is a basic workflow to check the lock on major version (to lock some files on certified versions)
name: Check fileset lock
on: [push, pull_request]
concurrency:
group: check-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
checkmajorversion:
name: Check lock on fileset unalterable_files with generate_filelist_xml.php
runs-on: ubuntu-latest
# Do not run schedule on forks
if: |
github.repository == 'Dolibarr/dolibarr'
|| github.event.schedule == false
steps:
- uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
coverage: none # disable xdebug, pcov
- name: Run generate_filelist_xml.php
run: |
# shellcheck disable=2086
dev/build/generate_filelist_xml.php checklock=auto unalterable_files

View File

@@ -33,7 +33,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:

View File

@@ -33,7 +33,7 @@ jobs:
github.repository == 'Dolibarr/dolibarr'
|| github.event.schedule == false
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:

View File

@@ -37,7 +37,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v5
- uses: actions/checkout@v6
# Get PHP and addons
- name: Setup PHP
id: setup-php

View File

@@ -30,7 +30,7 @@ jobs:
# if: false
# Checkout git sources to analyze
- uses: actions/checkout@v5
- uses: actions/checkout@v6
# Try to get the list of modified files into steps.changed-php.outputs.all_changed_files
#- name: Get changed files
@@ -109,6 +109,10 @@ jobs:
coverage: none # disable xdebug, pcov
tools: phpcs
# Install perltidy and perlcritic
- name: Install perltidy and perlcritic
run: sudo apt-get update && sudo apt-get install -y perltidy libperl-critic-perl
# Run all the precommit tools (defined into pre-commit-config.yaml).
# We can force exclusion of some of them here.
- name: Run pre-commit hooks
@@ -153,7 +157,7 @@ jobs:
ls -l ~/.cache/pre-commit/
- name: Convert Raw Log to Annotations
uses: mdeweerd/logToCheckStyle@v2025.1.1
uses: mdeweerd/logToCheckStyle@v2025.11.2
if: ${{ failure() }}
with:
in: ${{ env.RAW_LOG }}

View File

@@ -37,7 +37,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
@@ -167,7 +167,7 @@ jobs:
for /f "tokens=2 delims==" %%A in ('doskey /m:err') do EXIT /B %%A
- name: Convert Raw Log to Annotations
uses: mdeweerd/logToCheckStyle@v2025.1.1
uses: mdeweerd/logToCheckStyle@v2025.11.2
if: ${{ failure() }}
with:
in: ${{ env.PHPUNIT_LOG }}

View File

@@ -3,7 +3,7 @@ exclude: (?x)^( htdocs/includes/ckeditor/.*|(\.(?!github/workflows)[^/]*/.*))$
repos:
# Several miscellaneous checks and fix (on yaml files, end of files fix)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
# This hook tests the name of the branch and return an error if the name is
# 'develop' or an official version 'x.y'
@@ -60,13 +60,13 @@ repos:
# Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos
- repo: https://github.com/gitleaks/gitleaks.git
rev: v8.24.0
rev: v8.29.0
hooks:
- id: gitleaks
# Check github actions
- repo: https://github.com/rhysd/actionlint
rev: v1.7.7
rev: v1.7.8
hooks:
- id: actionlint
@@ -193,7 +193,7 @@ repos:
# Check format of yaml files
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.36.2
rev: v1.37.1
hooks:
- id: yamllint
args:
@@ -246,7 +246,7 @@ repos:
# Check some shell scripts
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.10.0.1
rev: v0.11.0.1
hooks:
- id: shellcheck
args: [-W, "100"]
@@ -274,3 +274,21 @@ repos:
|htdocs/install/pgsql/functions/functions.*\.sql
|htdocs/modulebuilder/template/sql/.*\.sql
)$
- repo: https://github.com/perltidy/perltidy
rev: '20250105.03'
hooks:
- id: perltidy
# virtualmin excuded - reason https://github.com/Dolibarr/dolibarr/pull/36370#issuecomment-3565101823
exclude: (?x)^
(dev/build/perl/virtualmin/dolibarr.pl
)$
args: [ --tabs, --nola ]
- repo: https://github.com/henryykt/pre-commit-perl
rev: v0.0.5
hooks:
- id: perlcritic
# virtualmin excuded - reason https://github.com/Dolibarr/dolibarr/pull/36370#issuecomment-3565101823
exclude: (?x)^
(dev/build/perl/virtualmin/dolibarr.pl
)$

320
ChangeLog
View File

@@ -6,34 +6,326 @@ English Dolibarr ChangeLog
For users:
----------
NEW: Need PHP 7.2 as minimum version
NEW: Module datapolicy moved as stable (for anonimization features)
NEW: #31723 - Improve project overview: Hide paid orders (#35524)
NEW: #35700 : Throw an error when validating a propal, order, supplier with a product no more in sale/purchase… (#35709)
NEW: Accountancy - Accounting by payment type (#34729)
NEW: Accountancy - Add accounting for discounts (#35977)
NEW: Accountancy - Add a protection on various payment for auxiliary account on general account not centralized (#35720)
NEW: Accountancy - Add field centralized on import/export (#35872)
NEW: Accountancy - Add hook on export filename (#35188)
NEW: Accountancy - Add reconcile on general accounting account - SQL part (#35994)
NEW: Accountancy - Analytical axis (SQL Structure) (#34738)
NEW: Accountancy - Manual input - Add script to greyed out subledger_account if general ledger is not centralized (#35855)
NEW: Accountancy - Transaction - Add verification on centralized account (#35824)
NEW: Accountancy - Various payment - Add script to greyed out subledger_account if general ledger is not centralized (#35842)
NEW: Add a boolean for lines in api and $properties (#34293)
NEW: Add accounting export mode for ISTEA (#36006)
NEW: add a limit to avoid too many answer in agenda view. Add warning if limit has been reached.
NEW: Add a page to edit http security headers of application (#34941)
NEW: Add auto-reference generation for tasks (like in project) in API (#35981)
NEW: Add column ref_ext and note_private for membership
NEW: Add column thirdparty ref_customer and ref_supplier in project list
NEW: Add column title in emailing and add more filters
NEW: add combining characters (accents, cedilla...) codes in dol_string_unaccent() (#35130)
NEW: add company date birth (SQL structure) (#34854) (UI) (#34861)
NEW: add conditional supplier price display (#35900)
NEW: Add configuration for default timesheet menu (#35805)
NEW: Add contact tab on product service (#35914)
NEW: Add directory navigation to Web Portal Shared Documents (#35443)
NEW: Added Messaging and agenda tabs on order and shipments (#34859)
NEW: Add event when installing a module in the security event list.
NEW: add extrafield option "empty on clone" (#34866)
NEW: add fields usage_opportunity, usage_task, usage_bill_time for project import (#35301)
NEW: Add filter on agenda event progression on agenda page
NEW: add free numbering module for members (#35636)
NEW: add global search for resource object (#36043)
NEW: add hidden const to get response header in geturlcontent function (#34781) (#34824)
NEW: add hook getListOfModels (#34626)
NEW: Add hook on calcula_price() and get_default_tva()
NEW: Add hooks in webportal (#35326)
NEW: add hook when printing new card button on thirdparty list (#36350)
NEW: add hourly rate in list of users
NEW: Add missing parameters for menus on webportal hook (#35550)
NEW: Add option PDF_PURCHASE_INVOICE_HIDE_VAT
NEW: Add option PROJECT_CAN_ALWAYS_LINK_TO_ALL_CUSTOMERS
NEW: Add option to create simple standalone shipment of non origin (#35651)
NEW: Add option to create standalone reception (#36134)
NEW: add private and public note on ticket (#35303)
NEW: add product_type field on fichinter (preparing subtotal) (#36196)
NEW: Add regions for CONGO, THE DEMOCRATIC REPUBLIC OF THE;CD (#36340)
NEW: ADD Send mail for reception / Delivery (#34829)
NEW: Add setup page to concat natively files on invoice PDF.
NEW: add shipping address to propal (#34441)
NEW: Add Sign feature on shipments (#34640)
NEW: Add sms reminder in reminder of agenda events (#35239)
NEW: Add SQL table for expensereport line extrafields support (#36251)
NEW: add supplier invoice, order and supplier order tag filter and bulk insert and statistics order and supplier order (#35399)
NEW: add supplier payment mail template (#35877)
NEW: add tags on proposals and supplier proposals and in statistics (#35553)
NEW: Add task categories 1/3 (#35848)
NEW: Add tasks card hooks (#35616)
NEW: Add the "Dispute status" in list of invoice.
NEW: add the option to not synchronize thirdparty <--> member (#36033)
NEW: Add the widget funnel of opportunities
NEW: Add tpl files for standalone shipment (#35624)
NEW: Add tpl loader for discounts.tpl.php (#34798)
NEW: Add Transfer Number (#35665)
NEW: Add Type, Description columns to Project Overview Expense Reports (#36214)
NEW: Add user permission for create/edit/delete supplier prices (#35940)
NEW: Allow omission of ODT template name when generating ODT and PDF (#35701)
NEW: Better navigation and report into database admin tools
NEW: Button to create a proposal and sale order from a contract always on
NEW: Can add info of main IT service provider in setup.
NEW: can admin payments extrafields (#34822)
NEW: Can drag and drop in BOM card
NEW: Can force_install_dolibarrpassword for automatic installation (#34537)
NEW: Can have a tooltip picto on title of column and keep autotruncation of label. Tooltip is show at begin of text.
NEW: Can show both currency code and symbol into the select of currency
NEW: Can sort on employee in holiday balance. Add link to go to history.
NEW: Can update value of timespent with last task hourly rate (#36018)
NEW: Can urlencode substitution variable of constants
NEW: Can view/list/edit the dispute status of an invoice
NEW: Change the path for the mailing files (#34878)
NEW: Constant ORDER_MASS_ACTION_BILLED_LINK_EXPEDITIONS (#34617)
NEW: const MENU_HIDE_EMAIL_TEMPLATES to hide email templates setup in Tools menu (#35739)
NEW: Create simple shipment of non origin (#35604)
NEW: Currency for the Democratic Republic of Congo added. (#36104)
NEW: Customized step in duration select (#34652)
NEW: Dashboard - Add option in ihm to disable MRP thumb (#36185)
NEW: date function related to holiday can accept country id in addition to country code
NEW: DEV Can set color of the on/off button.
NEW: Disable by default obfuscation methods and function in extrafields evaluable strings. Can re-enable with MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL=1
NEW: Discount split more than two parts (#34782)
NEW: Display company logo on kanban view (#34520)
NEW: dol_sort_array can be used with 2 sorting criteria.
NEW: Enhanced layout feature for emailing
NEW: Enhance popup for image preview (show size in title, can restore small view, always show the Rotate button).
NEW: Enhance the system for warnings on module activation
NEW: execute hook addMoreActionsButtons on bank card (#35598)
NEW: extrafields: add field to link a field to a module (#34416)
NEW: Feature to merge duplicate members (#35308)
NEW: generate renewal proposal for contracts (#35120)
NEW: Holiday - Allow to specify a specific mail address from (#36184)
NEW: hook allowing external modules to replace the behavior of fetchObjectLinked() (#34724)
NEW: hooks `showInputExtraField` and `showOutputExtraField` to override ExtraFields::show(Input|Output)Field (#35496)
NEW: implement box on product and interventional index page (#34629)
NEW: import subscriptions (#35612)
NEW: Introduce getCurrency(). $conf is no more allowed into computed formulae.
NEW: Invert logic of default date in proposal/order/invoice creation: Need option to NOT autofill instead of the opposite.
NEW: line input multicurrency price with tax (#35064)
NEW: Major overhaul of DataPolicyCron and add Recruitment policy (#34704)
NEW: Make the public contact form with experimental status
NEW: Minimal version of PHP is now 7.2
NEW: More index for memberships table
NEW: More information on the user credential section
NEW: More webportal feature - Can add shared files and thirdparty documents (#35391)
NEW: New hook mergePdf (#34707)
NEW: On invoice, show also nb of credit notes notyet converted for consumption
NEW: Option to clone parent categories on variant creation (#35806)
NEW: Output of category tag is nicer for long subcategories.
NEW: Parent project column in list of projects (#36177)
NEW: Paymentok validate invoice if not already done (#35564)
NEW: PDF Show customer balance on invoice date (#34800)
NEW: possibility to define global entity in user param (#35908)
NEW: Add messaging and agenda features to proposals (#34883)
NEW: public and private note can be shown on contact list
NEW: Public donation page (#35565)
NEW: public pages donation, ticket and member use captcha setup (#35913)
NEW: Rework of the management of the card and fields on the web portal (#36076)
NEW: Save the BAN and RUM for SEPA into database not just file.
NEW: search all facture rec (#34563)
NEW: Show cron last result and output in info (#36028)
NEW: Show full date with seconds in the tooltip of date of event
NEW: Show the link to download the zip of a module on module setup
NEW: Show warning on banner when an email is not valid
NEW: The check file feature can limit check on unalterable files only
NEW: The flag "Dispute open" make the status in Red.
NEW: The PHP info is in a popup in install page.
NEW: update country list (#34865)
NEW: Update Incoterms to 2025 standards and add new terms (#36041)
NEW: Upgrade ACE editor to 1.43.12
NEW: User/Date in the Follow tab are more condensed.
NEW: We added a hook to allow us to modify the Prospect Customer drop down… (#25635)
NEW: Withholdingtax how VatRefund (#34649)
For developers:
---------------
* Introducing the TRIGGER_PREFIX property to force developers to use unique triggerkey per business object, limit also code to business CRUD events and identity when it is not.
NEW: Introducing the TRIGGER_PREFIX property to force developers to use unique triggerkey per business object, to limit code to business CRUD events and report warning when it is not.
NEW: add extraparams field in llx_categorie (#35975)
NEW: Add prepare() method to DoliDB class (rebuild) (#35249)
NEW: Add function to split a discount in 2 by API REST (#34786)
NEW: Add a new API "product lots" (#36243)
NEW: Add API for Holidays/Leaves
NEW: add api for members statistics (#35851)
NEW: add api List VAT (#35920)
NEW: add api_paiements.class.php (#34756)
NEW: Add contact management on project Api (#35459)
NEW: Add contact support on products in REST API (#35925)
NEW: Add country ID resolution from country code for thirdparty api (#36345)
NEW: Add getcontacts on api of interventional and proposal (#35589)
NEW: Add hook initialization for interventions API (#35203)
NEW: Add option API_ENABLE_COUNT_CALLS
NEW: Add thirdparty search on api list (#34634)
NEW: add timespent API endpoints for projects and tasks add also cascading assignment of contacts to tasks (#35897)
NEW: add upload api feature for shipment (#34639)
NEW: Allow creating contact via api with ISO code (#36322)
NEW: API endpoint for getting products in a warehouse (#35918)
NEW: API for getting, adding, deleting and/or modifying email templates (#35853)
NEW: API for handling mass mailing targets (#35603)
NEW: API GET endpoint for thirdparties types listing (c_typent) (#34751)
NEW: Api mass emailing (#35531)
NEW: API user/groups/ POST, PUT, DELETE + some hurl tests (#35903)
NEW: API User - Remove user from group (#35453)
NEW: Implement listTimespent method in api_projects.class.php (#36093)
NEW: qual fixes on api contract (#36066)
NEW: stock API GET movement (#36193)
WARNING:
--------
The following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* The deprecated column egroupware_id has been dropped.
* The deprecated column "egroupware_id" has been dropped from table llx_user.
* The property $sumpayed (duplicated of $totalpaid), $sumdeposit (duplicate of $totaldeposits) and $sumcreditnote (duplicate of $totalcreditnotes) has
been removed (there are replaced with the property that was a duplication of (same for $sumpayed_multicurrency, $sumdeposit_multicurrency, $sumcreditnote_multicurrency).
* Parameters $maxlen and $notooltip of Contract have been inverted to follow the standard. It was breaking the common use of getNomUrl() but if you were using the parameter
maxlen (rare) by using the old signature, result may be a tooltip that is no more visible on ref printed by you module.
* Removed array $MAP_ID_TO_CODE that was a duplicate of array "array_flip($categ->MAP_ID)"
* Parameters $maxlen and $notooltip of Contract have been inverted to follow the standard. It was breaking the common use of getNomUrl() but if you were
using the parameter maxlen (rare) by using the old signature, result may be just a tooltip that is no more visible when mous over the contract ref shown by your module.
* Removed array $MAP_ID_TO_CODE that was a duplicate of the array "array_flip($categ->MAP_ID)"
* The signature of the Sale order ->cancel() method and shipment ->cancel() has been modified to introduce the $user param like for other methods that modify a status.
* Adding new document templates must be done by adding files into the mymodule/core/modules/xxx/doc directory. Adding files into custom directory with the
same path than the core path without using a mymodule directory is now forbidden.
* The directory theme/common/octicons has been removed
* The library timepicker.js has been removed. Was not used by Dolibarr.
* Because of new TRIGGER_PREFIX property triggers SUPPLIER_PRODUCT_BUYPRICE_XXX are renamed to PRODUCT_BUYPRICE_XXX.
* Function img_pdf() has been removed. Replace it with img_picto('', 'pdf.png') if you were using it.
* Adding new "document generation templates" must be done by adding files into the mymodule/core/modules/xxx/doc directory. Adding files into custom directory with the
same path than the core path, without using a "mymodule" directory, is now forbidden.
* The directory theme/common/octicons has been removed. No resource was used by Dolibarrfrom this directory.
* The library timepicker.js has been removed. Was no more used by Dolibarr since a long time.
* Because of the new TRIGGER_PREFIX property, the triggers SUPPLIER_PRODUCT_BUYPRICE_XXX are renamed into PRODUCT_BUYPRICE_XXX.
* Function img_pdf() has been removed. Replace it with img_picto('', 'pdf') if you were using it.
* The method run_trigger() was deprecated 10+ years ago in favor of runTrigger(). It has been removed. Change your trigger file if you still use it.
* Property ->picto of module descriptors must contains the image extension if it is not a font awesome tag. Example: $this->picto="mymoduleimg.png";
* Stock movement API GET method output variable names have been harmonized with POST input parameter names
* Stock movement API GET method output variable names has been harmonized with POST input parameter names
* Concatenation into computed property of extrafields is off by default. You can enable it from conf.php file by adding dol_concat to list of allowed function in $dolibarr_main_restrict_eval_methods,
For example: $dolibarr_main_restrict_eval_methods='getDolGlobalString,getDolGlobalInt,getDolCurrency,fetchNoCompute,hasRight,isModEnabled,isStringVarMatching,abs,min,max,round,dol_now,dol_concat,preg_match';
* Old variable $obj and $object are no more allowed into on the fly evaluated strings like computed or conditions on extrafields. Use $objectoffield to get current object
Also if you were using temporary variables int a computed extrafields, the nameot temporary variable must match $var123.
* The hidden constant MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL in database has been replaced with the
variable $dolibarr_main_allow_unsecured_special_chars_in_dol_eval into file conf/conf.php
* $conf use into "computed formulae" of etrafields is now deprecated (not yet forbidden). You can replace use of $conf->currency by the new method getCurrency() and $conf->global->xxx by getDolGlobalString('xxx').
* $user->rights->module->perms is also deprecated. You can use $user->hasRight() instead.
* The API endpoint /proposals/{id}/contact/{contactid}/{type}/{source} is now {id}/contact/{contactid}/{type} to match same behaviour than order and invoices.
***** ChangeLog for 22.0.3 compared to 22.0.2 *****
FIX: 16.0: extrafield of type link to category causes SQL error in selectForFormsList() (#36074)
FIX: 20.0 ajax_constantonoff + FormSetup were ignoring custom css class (cssClass / $morecss) (#36039)
FIX: #33741 FIX: #35632
FIX: #35247 FIX: #35950 Using same option for landing page and home page
FIX: #35519 (security) missing check user rights (#35527)
FIX: #35520 FIX: #35522
FIX: #35568 (#35569)
FIX: #35573 FIX: #35241
FIX: #35634 (#35912)
FIX: #35766: Update buying price INT Float (#35769)
FIX: #35780
FIX: #35782
FIX: #35784
FIX: #35922 Lines of orders - Status filter unexpected beahavior (#35924)
FIX: #36025 Accountancy - Error when cloning directly from accounting entry (#36034)
FIX: #36046 enabling extrafieldmanaged to enable deletion of records from the llx_salay_extrafields table
FIX: #36113 (#36116)
FIX: access problem when label is used for next/prev (#35933)
FIX: Accountancy - Admin personalized report - Remove duplicate button (#35721)
FIX: Accountancy - General setup - Missing form on UpdateMask (#35735)
FIX: Accountancy - Missing subledger information on mass cloning (#35777)
FIX: Accountancy - Printing the subsidiary ledger returns the general ledger (#35719)
FIX: Accountancy - Print subledger balance return general balance (#35712)
FIX: Accountancy - Problem with general setup (#36067)
FIX: Accountancy - Return on wrong page on y/n button (#35978)
FIX: Add missing left join to filter by extrafields (#36092)
FIX: add possibility to override authoritative dns (#35699)
FIX: Allow decimals on services duration (#36031)
FIX: avoid link problem with employee list context (#36125)
FIX: avoid NULL value (#36126)
FIX: avoid php warning (#35756)
FIX: avoid php warning (#35953)
FIX: avoid php warnings (#35492)
FIX: Bad label for column title on multicurency
FIX: bad name for target import table (#35615)
FIX: broken feature ! (#35906)
FIX: Can approve holidays when negative balance (#36144)
FIX: categories: sql error in link extrafields targettings categories (#36236)
FIX: check if category module is enabled (#35770)
FIX: check if service is activated only for api product (#35911)
FIX: check if zip file of website exists (#35879)
FIX: Clear filter
FIX: clone of cron tasks
FIX: conflict between $user->id and $object->id (#36225)
FIX: create invoice from order using API and multi-entity (#35654)
FIX: day of ticket on takePOS. Backport 6abdb6e. (#35745)
FIX: Deletion of a donation. Button was disabled.
FIX: detection of setup not done with
FIX: dol_escape_htmltag in extrafields_view (#36136)
FIX: doubled display of PRoduct Stokable checkbox when STOCK_SUPPORTS_SERVICES on service edit card (#36138)
FIX: Email template fetching (#35738)
FIX: Error 500 on api if cache is on and directory does not exists
FIX: extra-field list depend on parent extra-filed list on direct edit (#35803)
FIX: filter on note lost when sorting company list
FIX: Hide AWP if product has no stock managed
FIX: Import/Export - Do not list imports or exports of Builder module backups of module descriptor files (#36192)
FIX: In shipment creation process, if product is not manage in stock, Dolibarr should not display a "low stock warning" (#36139)
FIX: in shippement creation with SHIPMENT_SUPPORTS_SERVICES and/or STOCK_DISALLOW_NEGATIVE_TRANSFER and/or stockable_product there are inconsistencies (#36140)
FIX: Invoice Situation - Octopus - Column offset for amounts greater than 5 digits (#36124)
FIX: Invoice Situation - Octopus - Shipping block overlap issue (#36122)
FIX: Invoice Situation - Octopus - Show remaintopay at bottom (#36121)
FIX: invoices payments on multicurrencies being converted as int (#35622)
FIX: Knowledge management - Button ReOpen show in draft mode (#36008)
FIX: Label shown when value is empty
FIX: late customer orders are not shown on start page (#36200)
FIX: link to sort of target email page
FIX: MAIN_AUTOFILL_DATE in supplier invoice display 01/01/1970 (#36087)
FIX: MAIN_SEE_SUBORDONATES sql request error (#35896)
FIX: Missing begin transaction, The status of customer was not
FIX: missing check if partership is enabled (#36169)
FIX: missing entity field (#36086)
FIX: missing entity filter (#35517)
FIX: missing entity filter (#35857)
FIX: missing entity filters + wrong widget name (#35873)
FIX: missing "printFieldListValue" hook (#35990)
FIX: missing prospect/customer category translation (#35814)
FIX: Must show unit price when price is not for quantity 1
FIX: muticompany compatibility (wrong sharing name) (#36013)
FIX: my previous fix was incompatible with Thomas' fix from PR#35590 (#35890)
FIX: no emails sent when closing a ticket (#35874)
FIX: notification email not sent : NOTIFICATION_EMAIL_FROM is replaced with MAIN_MAIL_EMAIL_FROM if it's empty (#35881)
FIX: notifications: correctly report email delivery errors (#35864)
FIX: not possible to search for billed and not billed supplier orders in the list (#35680)
FIX: Perf for bom select (#35871)
FIX: Performance Problem on load stats command (#35785)
FIX: pgsql: error when calculating depreciations (#34213)
FIX: php 8+ warnings when creating deposits (#35582)
FIX: prices must be HT in dolistore browser
FIX: product stock lists: prevent SQL error when filtering on physical stock (#36038)
FIX: resize iban column to support encryption (#36237)
FIX: Select correct approver when making a leave request for someone else (#36118)
FIX: Situation percent set as 0 when adding line on situation invoices (#35999)
Fix: sql error if LIST_OF_QUALIFIED_INVOICES_LIMIT_DEFINED is used (#36135)
FIX: sql syntax error (#35588)
FIX: Status if thirdparty not synchronized with status WON of
FIX: substitutions on subject of the sent email reminder of the event (#35621)
FIX: The IBAN into EPC qr code must use the default bank account if not
FIX: The order closing date was not filled in during the shipment validation (workflow module). (#36235)
FIX: The status of customer was not synchronized with opportunity status
FIX: thirdparty was never notified. Passing of contact ID information was not coherent. (#35590)
FIX: To have only the sender's entity when sending mail (#31053)
FIX: when creating a ticken on backend and adding a linked file, the 'notify thirdparty at creation' chackbox disappears. (#35595)
FIX: when display in view mode HTML extrafeilds content doubled (#36127)
FIX: Wrong cast on TVA rate when updating supplier order lines (#36106)
FIX: wrong check of hook return
FIX: wrong entity alias (#35821)
FIX: wrong entity filter (#35691)
FIX: wrong field name (#35728)
FIX: wrong getEntiy element name (#35771)
FIX: wrong number of categories by entity (#36111)
FIX: wrong socpeople id when multiple assigned + avoid php warnings (#35878)
***** ChangeLog for 22.0.2 compared to 22.0.1 *****

View File

@@ -2,7 +2,7 @@
![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg)
![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521)

View File

@@ -1,54 +1,94 @@
#!/usr/bin/perl
##no critic (InputOutput::RequireBriefOpen)
use strict;
use warnings;
#--------------------------------------------------------------------
# Start the generation of the development documentation with doxygen
#--------------------------------------------------------------------
# Determine the patho of this script
($DIR=$0) =~ s/([^\/\\]+)$//;
$DIR||='.';
( my $DIR = $0 ) =~ s/([^\/\\]+)$//;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
$OPTIONS="";
my $OPTIONS = "";
#$OPTIONS="-d Preprocessor";
$CONFFILE="dolibarr-doxygen.doxyfile";
my $CONFFILE = "dolibarr-doxygen.doxyfile";
use Cwd;
my $dir = getcwd;
print "Current dir is: $dir\n";
#print "Running dir for doxygen must be: $DIR\n";
if (! -s "dev/build/doxygen/$CONFFILE")
{
print "Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
print "\n";
if ( !-s "dev/build/doxygen/$CONFFILE" ) {
print
"Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
print "\n";
print "Change your current directory then, to launch the script, run:\n";
print '> perl .\dolibarr-doxygen-build.pl (on Windows)'."\n";
print '> perl ../dolibarr-doxygen-build.pl (on Linux or BSD)'."\n";
sleep 4;
exit 1;
print '> perl .\dolibarr-doxygen-build.pl (on Windows)' . "\n";
print '> perl ../dolibarr-doxygen-build.pl (on Linux or BSD)' . "\n";
sleep 4;
exit 1;
}
$SOURCE=".";
my $SOURCE = ".";
# Get version $MAJOR, $MINOR and $BUILD
$result = open( IN, "< " . $SOURCE . "/htdocs/filefunc.inc.php" );
if ( !$result ) { die "Error: Can't open descriptor file " . $SOURCE . "/htdocs/filefunc.inc.php\n"; }
while (<IN>) {
if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) { $PROJVERSION = $1; break; }
my $result = open( my $IN, "<", $SOURCE . "/htdocs/filefunc.inc.php" );
if ( !$result ) {
die "Error: Can't open descriptor file " . $SOURCE
. "/htdocs/filefunc.inc.php\n";
}
close IN;
($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
if ($MINOR eq '') { die "Error can't detect version into ".$SOURCE . "/htdocs/filefunc.inc.php"; }
my $PROJVERSION = "";
while (<$IN>) {
if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) {
$PROJVERSION = $1;
last;
}
}
close $IN;
if ( $PROJVERSION eq "" ) {
my $DOL_MAJOR_VERSION;
my $DOL_MINOR_VERSION;
my @VERSION_FILES = ( "filefunc.inc.php", "version.inc.php" );
foreach my $file (@VERSION_FILES) {
$result = open( my $IN, "<", $SOURCE . "/htdocs/$file" );
if ( !$result ) {
die "Error: Can't open descriptor file " . $SOURCE
. "/htdocs/$file\n";
}
while (<$IN>) {
if ( $_ =~ /define\('DOL_MAJOR_VERSION', '([\d\.a-z\-]+)'\)/ ) {
$DOL_MAJOR_VERSION = $1;
}
if ( $_ =~ /define\('DOL_MINOR_VERSION', '([\d\.a-z\-]+)'\)/ ) {
$DOL_MINOR_VERSION = $1;
}
}
close $IN;
}
$PROJVERSION = $DOL_MAJOR_VERSION . '.' . $DOL_MINOR_VERSION;
}
$version=$MAJOR.".".$MINOR.".".$BUILD;
( my $MAJOR, my $MINOR, my $BUILD ) = split( /\./, $PROJVERSION, 3 );
if ( !defined($MINOR) || $MINOR eq '' ) {
die "Error can't detect version from " . $SOURCE
. "/htdocs/filefunc.inc.php";
}
my $version = $MAJOR . "." . $MINOR . "." . $BUILD;
print "Running doxygen for version ".$version.", please wait...\n";
print "cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/".$version."/' | doxygen $OPTIONS - 2>&1\n";
$result=`cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
print "Running doxygen for version " . $version . ", please wait...\n";
print "cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/" . $version
. "/' | doxygen $OPTIONS - 2>&1\n";
$result =
`cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
print $result;

View File

@@ -4,85 +4,79 @@
# on PHP source files before running Doxygen.
# \author Laurent Destailleur
#--------------------------------------------------------------------
## no critic (InputOutput::RequireBriefOpen)
use strict;
use warnings;
# Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot
$file=$ARGV[0];
if (! $file)
{
my $file = $ARGV[0];
if ( !$file ) {
print "Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot\n";
exit;
}
open(FILE,$file) || die "Failed to open file $file";
while (<FILE>)
{
if ($_ =~ /\\version\s/i)
{
open( my $fh, "<", $file ) || die "Failed to open file $file";
while (<$fh>) {
if ( $_ =~ /\\version\s/i ) {
$_ =~ s/\$Id://i;
$_ =~ s/(Exp|)\s\$$//i;
$_ =~ s/(\\version\s+)[^\s]+\s/$1/i;
$_ =~ s/(\w)\s(\w)/$1_$2/g;
}
$_ =~ s/exit\s*;/exit(0);/i;
$i=0;
$len=length($_);
$s="";
$insidequote=0;
$insidedquote=0;
$ignore="";
while ($i < $len)
{
$c=substr($_,$i,1);
if ($c eq "\\")
{
if ($insidequote) { $ignore="'"; };
if ($insidedquote) { $ignore="\""; };
my $i = 0;
my $len = length($_);
my $s = "";
my $insidequote = 0;
my $insidedquote = 0;
my $ignore = "";
while ( $i < $len ) {
my $c = substr( $_, $i, 1 );
if ( $c eq "\\" ) {
if ($insidequote) { $ignore = "'"; }
if ($insidedquote) { $ignore = "\""; }
}
else
{
if ($c eq "'")
{
if (! $insidedquote)
{
$c="\"";
else {
if ( $c eq "'" ) {
if ( !$insidedquote ) {
$c = "\"";
#print "X".$ignore;
if ($ignore ne "'")
{
if ( $ignore ne "'" ) {
#print "Z".$ignore;
$insidequote++;
if ($insidequote == 2)
{
$insidequote=0;
if ( $insidequote == 2 ) {
$insidequote = 0;
}
}
}
#print "X".$insidequote;
}
elsif ($c eq "\"")
{
elsif ( $c eq "\"" ) {
#print "Y".$insidequote;
if ($insidequote)
{
$c="'";
if ($insidequote) {
$c = "'";
}
else
{
if ($ignore ne "\"")
{
else {
if ( $ignore ne "\"" ) {
$insidedquote++;
if ($insidedquote == 2)
{
$insidedquote=0;
if ( $insidedquote == 2 ) {
$insidedquote = 0;
}
}
}
}
$ignore="";
$ignore = "";
}
$s.=$c;
$s .= $c;
$i++;
}
print $s;
}
close(FILE);
close($fh);

View File

@@ -1,4 +1,7 @@
#!/usr/bin/perl
use strict;
use warnings;
#--------------------------------------------------------------------
# Script to get version of a source file
# Does not work with cygwin cvs command on Windows.
@@ -7,15 +10,18 @@
# Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot
$file=$ARGV[0];
if (! $file)
{
$file = $ARGV[0];
if ( !$file ) {
print "Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot\n";
exit;
}
$commande='cvs status "'.$file.'" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
$commande =
'cvs status "'
. $file
. '" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
#print $commande;
$result=`$commande 2>&1`;
$result = `$commande 2>&1`;
print $result;

View File

@@ -43,5 +43,5 @@ DoliWampWillStartApacheMysql=Die DoliWamp-Installation wird nun starten oder Apa
OldVersionFoundAndMoveInNew=Eine alte Datenbankversion wurde gefunden und verschoben, um von der neuen Dolibarr-Version verwendet zu werden.
OldVersionFoundButFailedToMoveInNew=Eine alte Datenbankversion wurde gefunden, konnte jedoch nicht verschoben werden, um mit der neuen Dolibarr-Version verwendet zu werden.
DLLMissing=Your Windows installation is missing The "Micrsoft Visual C++ Redistributable for Visual Studio 2017" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after.
DLLMissing=Your Windows installation is missing The "Microsoft Visual C++ Redistributable for Visual Studio 2017" component. Please install the 32-bit version (vc_redist.x86.exe) first (you can find it at https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-supported-redistributable-version) and restart DoliWamp installation/upgrade after.
ContinueAnyway=Fahren Sie trotzdem fort (der Installationsvorgang kann ohne diese Voraussetzung fehlschlagen).

View File

@@ -26,6 +26,7 @@
if (!defined('NOREQUIREDB')) {
define('NOREQUIREDB', '1'); // Do not create database handler $db
}
define('NOREQUIREVIRTUALURL', 1);
$sapi_type = php_sapi_name();
$script_file = basename(__FILE__);
@@ -37,6 +38,8 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
exit(1);
}
define('DOL_DOCUMENT_ROOT', dirname(dirname($path)).'/htdocs');
require_once $path."../../htdocs/master.inc.php";
require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
@@ -48,11 +51,15 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
$includecustom = 0;
$includeconstants = array();
$buildzip = 0;
$release = '';
$checklock = '';
print '***** '.$script_file.' *****'."\n";
if (empty($argv[1])) {
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1]\n";
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
print "\n";
print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=ES:CONST_XX_IS_ON includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n";
print "\n";
print "Generate the file filelist-x.y.z[-mybuild].xml with signature of files. ";
@@ -63,6 +70,8 @@ if (empty($argv[1])) {
print "and if a specific setup/parameter need to be included into the signature for check:\n";
print "- dolibarr_constants\n";
print "\n";
print "If used with parameter 'check_unalterable_files', it will validate that the signature generated is the samethan the one found into lockedfiles.txt";
print "\n";
exit(1);
}
@@ -76,9 +85,15 @@ while ($i < $argc) {
if (!empty($result["release"])) {
$release = $result["release"];
}
if (!empty($result["checklock"])) {
$checklock = $result["checklock"];
}
if (!empty($result["includecustom"])) {
$includecustom = $result["includecustom"];
}
if (preg_match('/unalterable_files/', strval($argv[$i]))) {
$checksource = 'unalterable_files';
}
if (preg_match('/includeconstant=/', strval($argv[$i]))) {
$tmp = explode(':', $result['includeconstant'], 3); // $includeconstant has been set with previous parse_str()
if (count($tmp) != 3) {
@@ -93,9 +108,10 @@ while ($i < $argc) {
$i++;
}
if (empty($release)) {
print "Error: Missing release parameter\n";
if (empty($release) && empty($checklock)) {
print "Error: Missing release or checklock parameter\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
exit(2);
}
@@ -109,170 +125,217 @@ if ($tmpver[0] == 'auto') {
$release .= '-'.$tmpver[1];
}
}
// If release is auto, we take current version
$tmpver = explode('-', $checklock, 2);
if ($tmpver[0] == 'auto') {
$checklock = DOL_VERSION;
if (!empty($tmpver[1]) && $tmpver[0] == 'auto') {
$checklock .= '-'.$tmpver[1];
}
}
if (empty($includecustom)) {
$tmpverbis = explode('-', $release, 2);
if (empty($tmpverbis[1])) {
if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit(3);
$checklockmajorversion = '';
if ($checklock) {
$checklockmajorversion = preg_replace('/-.*$/', '', $checklock);
$checklockmajorversion = preg_replace('/\..*/', '', $checklockmajorversion);
$checklockmajorversion .= '.0.0';
}
if ($release) {
if (empty($includecustom)) {
$tmpverbis = explode('-', $release, 2);
if (empty($tmpverbis[1])) {
if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exactly the same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "\n";
exit(3);
}
} else {
$tmpverter = explode('-', DOL_VERSION, 2);
if ($tmpverter[0] != $tmpverbis[0]) {
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "\n";
exit(4);
}
}
} else {
$tmpverter = explode('-', DOL_VERSION, 2);
if ($tmpverter[0] != $tmpverbis[0]) {
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit(4);
if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "\n";
exit(5);
}
}
} else {
if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit(5);
}
}
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Release : ".$release."\n";
print "Include custom dir in signature : ".(empty($includecustom) ? 'no' : 'yes')."\n";
print "Include constants in signature : ".(empty($includeconstants) ? 'none' : '');
foreach ($includeconstants as $countrycode => $tmp) {
foreach ($tmp as $constname => $constvalue) {
print $constname.'='.$constvalue." ";
}
}
print "\n";
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
$outputdir = dirname(dirname(dirname(__FILE__))).'/htdocs/install';
print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
$checksumconcat = array();
$outputfile = $outputdir.'/filelist-'.$release.'.xml';
$fp = fopen($outputfile, 'w');
if (empty($fp)) {
print 'Failed to open file '.$outputfile."\n";
if ($checklock && empty($checksource)) {
print 'Error: When action "checklock" is set, second parameter must be the scope family to check, for example "unalterable_files"'."\n";
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
print "\n";
exit(6);
}
$gitcommit = 'seetag';
$branchname = preg_replace('/^(\d+\.\d+)\..*$/', '\1', $release); // Keep only x.y into x.y.z
$fileforgit = dirname(dirname(dirname(__FILE__))).'/.git/refs/heads/'.$branchname;
print "Try to get last commit ID from file ".$fileforgit."\n";
$fileforgitcontent = '';
if (file_exists($fileforgit)) {
$fileforgitcontent = file_get_contents($fileforgit);
if ($release) {
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Version of target release : ".$release."\n";
print "Include custom dir in signature : ".(empty($includecustom) ? 'no' : 'yes')."\n";
print "Include constants in signature : ".(empty($includeconstants) ? 'none' : '');
foreach ($includeconstants as $countrycode => $tmp) {
foreach ($tmp as $constname => $constvalue) {
print $constname.'='.$constvalue." ";
}
}
print "\n";
}
if (empty($fileforgitcontent)) {
print "Failed to get the last commit ID (are you on the branch for the release branch name ".$branchname." ?). We will use an empty value for gitcommit.\n";
if ($checklock) {
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Version to check in lockedfiles.txt : ".$checklockmajorversion."\n";
print "Check source : ".$checksource."\n";
}
if ($release) {
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
$outputdir = dirname(dirname(dirname(__FILE__))).'/htdocs/install';
print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
}
$gitcommit = trim($fileforgitcontent);
fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'" gitcommit="'.$gitcommit.'">'."\n");
$needtoclose = 0;
foreach ($includeconstants as $countrycode => $tmp) {
fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
foreach ($tmp as $constname => $constvalue) {
$valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
$checksumconcat[] = $valueforchecksum;
fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
// Build the XML file
if ($release) {
$checksumconcat = array();
$outputfile = $outputdir.'/filelist-'.$release.'.xml';
$fp = fopen($outputfile, 'w');
if (empty($fp)) {
print 'Failed to open file '.$outputfile."\n";
exit(7);
}
fputs($fp, '</dolibarr_constants>'."\n\n");
}
fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
$gitcommit = 'seetag';
$branchname = preg_replace('/^(\d+\.\d+)\..*$/', '\1', $release); // Keep only x.y into x.y.z
$fileforgit = dirname(dirname(dirname(__FILE__))).'/.git/refs/heads/'.$branchname;
print "Try to get last commit ID from file ".$fileforgit."\n";
$fileforgitcontent = '';
if (file_exists($fileforgit)) {
$fileforgitcontent = file_get_contents($fileforgit);
}
if (empty($fileforgitcontent)) {
print "Failed to get the last commit ID (are you on the branch for the release branch name ".$branchname." ?). We will use an empty value for gitcommit.\n";
}
$gitcommit = trim($fileforgitcontent);
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'" gitcommit="'.$gitcommit.'">'."\n");
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
foreach ($includeconstants as $countrycode => $tmp) {
fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
foreach ($tmp as $constname => $constvalue) {
$valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
$checksumconcat[] = $valueforchecksum;
fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
fputs($fp, '</dolibarr_constants>'."\n\n");
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_htdocs_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
fputs($fp, md5(join(',', $checksumconcat))."\n");
fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n\n");
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
// Add the checksum for the part in scripts
$checksumconcat = array();
fputs($fp, '<dolibarr_script_dir version="'.$release.'">'."\n");
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
$regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
$files = dol_dir_list(dirname(__FILE__).'/../../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../scripts', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_script_dir>'."\n");
fputs($fp, '</dolibarr_htdocs_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
$md5htdocsdir = md5(join(',', $checksumconcat));
fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
fputs($fp, $md5htdocsdir."\n");
fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n\n");
// Add the checksum for the part in scripts
$checksumconcat = array();
fputs($fp, '<dolibarr_scripts_dir version="'.$release.'">'."\n");
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
$regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
$files = dol_dir_list(dirname(__FILE__).'/../../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../scripts', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_scripts_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
$md5scriptsdir = md5(join(',', $checksumconcat));
fputs($fp, '<dolibarr_scripts_dir_checksum>'."\n");
fputs($fp, $md5scriptsdir."\n");
fputs($fp, '</dolibarr_scripts_dir_checksum>'."\n\n");
}
asort($checksumconcat); // Sort list of checksum
fputs($fp, '<dolibarr_script_dir_checksum>'."\n");
fputs($fp, md5(join(',', $checksumconcat))."\n");
fputs($fp, '</dolibarr_script_dir_checksum>'."\n\n");
// Add the checksum for the files into the scope of the unalterable system (record, read, export)
$checksumconcat = array();
fputs($fp, '<dolibarr_unalterable_files version="'.$release.'">'."\n");
if ($release) {
fputs($fp, '<dolibarr_unalterable_files version="'.$release.'">'."\n");
}
// Array of dir/files to include in the section
$arrayofunalterablefiles = array(
@@ -296,25 +359,34 @@ foreach ($arrayofunalterablefiles as $entry) {
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
if ($release) {
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
}
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
if ($release) {
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
} else {
$file = $entry['dir'].'/'.$entry['file'];
$dir = '';
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if (!file_exists($file)) {
@@ -323,60 +395,105 @@ foreach ($arrayofunalterablefiles as $entry) {
}
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
if ($release) {
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
}
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
if ($release) {
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
}
}
fputs($fp, '</dolibarr_unalterable_files>'."\n");
asort($checksumconcat); // Sort list of checksum
fputs($fp, '<dolibarr_unalterable_files_checksum>'."\n");
fputs($fp, md5(join(',', $checksumconcat))."\n");
fputs($fp, '</dolibarr_unalterable_files_checksum>'."\n\n");
$md5unalterable_files = md5(join(',', $checksumconcat));
if ($release) {
fputs($fp, '</dolibarr_unalterable_files>'."\n");
fputs($fp, '<dolibarr_unalterable_files_checksum>'."\n");
fputs($fp, $md5unalterable_files."\n");
fputs($fp, '</dolibarr_unalterable_files_checksum>'."\n\n");
// End of file
// End of file
fputs($fp, '</checksum_list>'."\n");
fclose($fp);
fputs($fp, '</checksum_list>'."\n");
fclose($fp);
}
print "\n";
if (empty($buildzip)) {
print "File ".$outputfile." generated.\n";
} else {
if ($buildzip == '1' || $buildzip == 'zip') {
$result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".zip generated.\n";
if ($release) {
if (empty($buildzip)) {
print "File ".$outputfile." generated.\n";
print "Signature for htdocs files: ".$md5htdocsdir."\n";
print "Signature for scripts files: ".$md5scriptsdir."\n";
print "Signature for the ".count($checksumconcat)." unalterable files: ".$md5unalterable_files."\n";
} else {
if ($buildzip == '1' || $buildzip == 'zip') {
$result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".zip generated.\n";
}
} elseif ($buildzip == '2' || $buildzip == 'gz') {
$result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".gz generated.\n";
}
}
} elseif ($buildzip == '2' || $buildzip == 'gz') {
$result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".gz generated.\n";
}
}
if ($checklock) {
print "Signature for unalterable files: ".$md5unalterable_files."\n";
$lockedfile = DOL_DOCUMENT_ROOT.'/../dev/lockedfiles.txt';
$checksuminlockedfile = '';
if (!file_exists($lockedfile)) {
print "Can't find the file ".$lockedfile.". No checksum to check\n";
} else {
// Now we check the content of lockedfiles.txt
$arraylocked = file($lockedfile);
foreach ($arraylocked as $line) {
$tmparray = preg_split("/\s+/", $line, 3);
if ($tmparray[0] == $checklockmajorversion) {
$checksuminlockedfile = $tmparray[2];
}
}
if (empty($checksuminlockedfile)) {
print "The major version ".$checklockmajorversion." is not locked on the scope ".$checksource." (file found but no matching entry found into dev/lockedfiles.txt).\n";
} elseif ($checksuminlockedfile != $md5unalterable_files) {
print "The major version ".$checklockmajorversion." is locked on scope '".$checksource."' to checksum ".$checksuminlockedfile."\n";
if ($checklockmajorversion != $checksource) {
print "The checksum now differs from the locked one, so we return an error.\n";
print "\n";
exit(10);
}
}
}
}
print "\n";
exit(0);

View File

@@ -1,4 +1,5 @@
#!/usr/bin/perl
## no critic (InputOutput::RequireBriefOpen)
#fetch Gravatars
use strict;
@@ -10,39 +11,44 @@ use Digest::MD5 qw(md5_hex);
my $size = 90;
my $output_dir = './avatars';
die("no .git/ directory found in current path\n") unless -d './avatars';
die("no .git repository found in current path\n") unless -r './.git';
mkdir($output_dir) unless -d $output_dir;
open(GITLOG, q/git log --pretty=format:"%ae|%an" |/) or die("failed to read git-log: $!\n");
open( my $GITLOG, '-|', q/git log --pretty=format:"%ae|%an" --reverse/ )
or die("failed to read git-log: $!\n");
my %processed_authors;
while(<GITLOG>) {
chomp;
my($email, $author) = split(/\|/, $_);
while (<$GITLOG>) {
chomp;
my ( $email, $author ) = split( /\|/, $_ );
next if $processed_authors{$author}++;
next if $processed_authors{$author}++;
my $author_image_file = $output_dir . '/' . $author . '.png';
my $author_image_file = $output_dir . '/' . $author . '.png';
#skip images we have
next if -e $author_image_file;
#skip images we have
next if -e $author_image_file;
#try and fetch image
#try and fetch image
my $grav_url = "http://www.gravatar.com/avatar/".md5_hex(lc $email)."?d=404&size=".$size;
my $grav_url =
"https://www.gravatar.com/avatar/"
. md5_hex( lc $email )
. "?d=404&size="
. $size;
warn "fetching image for '$author' $email ($grav_url)...\n";
warn "fetching image for '$author' $email ($grav_url)...\n";
my $rc = getstore($grav_url, $author_image_file);
my $rc = getstore( $grav_url, $author_image_file );
sleep(1);
sleep(1);
if($rc != 200) {
unlink($author_image_file);
next;
}
if ( $rc != 200 ) {
unlink($author_image_file);
next;
}
}
close GITLOG;
close $GITLOG;

File diff suppressed because it is too large Load Diff

View File

@@ -5,223 +5,288 @@
# \author (c)2005-2014 Laurent Destailleur <eldy@users.sourceforge.net>
# \contributor (c)2017 Nicolas ZABOURI <info@inovea-conseil.com>
#----------------------------------------------------------------------------
## no critic (InputOutput::ProhibitExplicitStdin,InputOutput::RequireBriefOpen)
use strict;
use warnings;
use Cwd;
use Term::ANSIColor;
$OWNER="ldestailleur";
$GROUP="ldestailleur";
$OWNER = "ldestailleur";
$GROUP = "ldestailleur";
@LISTETARGET=("ZIP"); # Possible packages
%REQUIREMENTTARGET=( # Tool requirement for each package
"TGZ"=>"tar",
"ZIP"=>"7z"
@LISTETARGET = ("ZIP"); # Possible packages
%REQUIREMENTTARGET = ( # Tool requirement for each package
"TGZ" => "tar",
"ZIP" => "7z"
);
%ALTERNATEPATH=(
);
%ALTERNATEPATH = ();
use vars qw/ $REVISION $VERSION /;
$REVISION='1.0';
$VERSION="3.5 (build $REVISION)";
$REVISION = '1.0';
$VERSION = "3.5 (build $REVISION)";
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
$Extension = $1;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
# Detect OS type
# --------------
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
if (! $OS) {
print "$PROG.$Extension was not able to detect your OS.\n";
if ( "$^O" =~ /linux/i || ( -d "/etc" && -d "/var" && "$^O" !~ /cygwin/i ) ) {
$OS = 'linux';
$CR = '';
}
elsif ( -d "/etc" && -d "/Users" ) { $OS = 'macosx'; $CR = ''; }
elsif ( "$^O" =~ /cygwin/i || "$^O" =~ /win32/i ) {
$OS = 'windows';
$CR = "\r";
}
if ( !$OS ) {
print "$PROG.$Extension was not able to detect your OS.\n";
print "Can't continue.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
sleep 2;
exit 1;
}
# Define buildroot
# ----------------
if ($OS =~ /linux/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
if ( $OS =~ /linux/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
}
if ($OS =~ /macos/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
if ( $OS =~ /macos/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
}
if ($OS =~ /windows/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"c:/temp";
$PROGPATH=$ENV{"ProgramFiles"};
if ( $OS =~ /windows/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "c:/temp";
$PROGPATH = $ENV{"ProgramFiles"};
}
if (! $TEMP || ! -d $TEMP) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
if ( !$TEMP || !-d $TEMP ) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
exit 2;
sleep 2;
exit 2;
}
$BUILDROOT="$TEMP/dolibarr-buildroot";
$BUILDROOT = "$TEMP/dolibarr-buildroot";
my $copyalreadydone = 0;
my $batch = 0;
my $copyalreadydone=0;
my $batch=0;
for (0..@ARGV-1) {
if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; }
if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; }
if ($ARGV[$_] =~ /^-*prefix=(.+)/i) {
$PREFIX=$1;
$FILENAMESNAPSHOT.="-".$PREFIX;
}
for ( 0 .. @ARGV - 1 ) {
if ( $ARGV[$_] =~ /^-*target=(\w+)/i ) { $target = $1; $batch = 1; }
if ( $ARGV[$_] =~ /^-*desti=(.+)/i ) { $DESTI = $1; }
if ( $ARGV[$_] =~ /^-*prefix=(.+)/i ) {
$PREFIX = $1;
$FILENAMESNAPSHOT .= "-" . $PREFIX;
}
}
$SOURCE="$DIR/../..";
$DESTI="$SOURCE/dev/build";
if ($ENV{"DESTIMODULES"}) { $DESTI = $ENV{"DESTIMODULES"}; } # Force output dir if env DESTIMODULES is defined
$NEWDESTI=$DESTI;
$SOURCE = "$DIR/../..";
$DESTI = "$SOURCE/dev/build";
if ( $ENV{"DESTIMODULES"} ) {
$DESTI = $ENV{"DESTIMODULES"};
} # Force output dir if env DESTIMODULES is defined
$NEWDESTI = $DESTI;
print "Makepack for modules version $VERSION\n";
print "Source directory: $SOURCE\n";
print "Target directory: $NEWDESTI\n";
# Ask module
print "Enter name for your module (mymodule, mywonderfulmondule, ... or 'all') : ";
$PROJECTINPUT=<STDIN>;
print
"Enter name for your module (mymodule, mywonderfullmodule, ... or 'all') : ";
my $PROJECTINPUT = <STDIN>;
chomp($PROJECTINPUT);
print "Move to ".$DIR." directory.\n";
print "Move to " . $DIR . " directory.\n";
chdir($DIR);
my @PROJECTLIST=();
if ($PROJECTINPUT eq "all")
{
opendir(DIR, $DIR) || return;
local @rv = grep { /^makepack\-(.*)\.conf$/ } sort readdir(DIR);
closedir(DIR);
foreach my $xxx (0..@rv-1) {
if ($rv[$xxx] =~ /^makepack\-(.*)\.conf$/)
{
@PROJECTLIST[$xxx]=$1;
}
}
my @PROJECTLIST = ();
if ( $PROJECTINPUT eq "all" ) {
opendir( my $DIR, $DIR ) or return;
local @rv = grep { /^makepack\-(.*)\.conf$/ } sort readdir($DIR);
closedir($DIR);
foreach my $xxx ( 0 .. @rv - 1 ) {
if ( $rv[$xxx] =~ /^makepack\-(.*)\.conf$/ ) {
@PROJECTLIST[$xxx] = $1;
}
}
}
else
{
@PROJECTLIST=($PROJECTINPUT);
else {
@PROJECTLIST = ($PROJECTINPUT);
}
# Loop on each projects
foreach my $PROJECT (@PROJECTLIST) {
$PROJECTLC=lc($PROJECT);
$PROJECTLC = lc($PROJECT);
if (! -f "makepack-".$PROJECT.".conf")
{
print "Error: can't open conf file makepack-".$PROJECT.".conf\n";
if ( !-f "makepack-" . $PROJECT . ".conf" ) {
print "Error: can't open conf file makepack-" . $PROJECT . ".conf\n";
print "\n";
print "For help on building a module package, see web page\n";
print "http://wiki.dolibarr.org/index.php/Module_development#Create_a_package_to_distribute_and_install_your_module\n";
print
"http://wiki.dolibarr.org/index.php/Module_development#Create_a_package_to_distribute_and_install_your_module\n";
print "makepack-dolibarrmodule.pl aborted.\n";
sleep 2;
exit 2;
sleep 2;
exit 2;
}
# Get version $MAJOR, $MINOR and $BUILD
print "Version detected for module ".$PROJECT." in file ".$SOURCE."/htdocs/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php";
$result=open(IN,"<".$SOURCE."/htdocs/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php");
$custom=false;
if (! $result) {
$result=open(IN,"<".$SOURCE."/htdocs/custom/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php");
if (! $result) {
die "Error: Can't open descriptor file ".$SOURCE."/htdocs/(or /htdocs/custom/)".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php for reading.\n";
}else{
$custom = true;
}
}
while(<IN>)
{
if ($_ =~ /this->version\s*=\s*'([\d\.]+)'/) { $PROJVERSION=$1; break; }
}
close IN;
print $PROJVERSION."\n";
print "Version detected for module "
. $PROJECT
. " in file "
. $SOURCE
. "/htdocs/"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php";
$result = open(
my $IN,
"<",
$SOURCE
. "/htdocs/"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php"
);
$custom = false;
if ( !$result ) {
$result = open(
my $IN,
"<",
$SOURCE
. "/htdocs/custom/"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php"
);
if ( !$result ) {
die "Error: Can't open descriptor file "
. $SOURCE
. "/htdocs/(or /htdocs/custom/)"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php for reading.\n";
}
}
else {
$custom = true;
}
while (<$IN>) {
if ( $_ =~ /this->version\s*=\s*'([\d\.]+)'/ ) {
$PROJVERSION = $1;
break;
}
}
close $IN;
print $PROJVERSION. "\n";
($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
if ($MINOR eq '')
{
print "Enter value for minor version for module ".$PROJECT.": ";
$MINOR=<STDIN>;
chomp($MINOR);
( $MAJOR, $MINOR, $BUILD ) = split( /\./, $PROJVERSION, 3 );
if ( $MINOR eq '' ) {
print "Enter value for minor version for module " . $PROJECT . ": ";
$MINOR = <STDIN>;
chomp($MINOR);
}
$FILENAME="$PROJECTLC";
$FILENAMETGZ="module_$PROJECTLC-$MAJOR.$MINOR".($BUILD ne ''?".$BUILD":"");
$FILENAMEZIP="module_$PROJECTLC-$MAJOR.$MINOR".($BUILD ne ''?".$BUILD":"");
if (-d "/usr/src/redhat") {
# redhat
$RPMDIR="/usr/src/redhat";
}
if (-d "/usr/src/RPM") {
# mandrake
$RPMDIR="/usr/src/RPM";
}
$FILENAME = "$PROJECTLC";
$FILENAMETGZ =
"module_$PROJECTLC-$MAJOR.$MINOR" . ( $BUILD ne '' ? ".$BUILD" : "" );
$FILENAMEZIP =
"module_$PROJECTLC-$MAJOR.$MINOR" . ( $BUILD ne '' ? ".$BUILD" : "" );
if ( -d "/usr/src/redhat" ) {
# redhat
$RPMDIR = "/usr/src/redhat";
}
if ( -d "/usr/src/RPM" ) {
# mandrake
$RPMDIR = "/usr/src/RPM";
}
# Choose package targets
#-----------------------
$target="ZIP"; # Dolibarr modules are this format
$CHOOSEDTARGET{uc($target)}=1;
$target = "ZIP"; # Dolibarr modules are this format
$CHOOSEDTARGET{ uc($target) } = 1;
# Test if requirement is ok
#--------------------------
foreach my $target (keys %CHOOSEDTARGET) {
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) {
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret=`"$req" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
# Not found error, we try in PROGPATH
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
foreach my $target ( keys %CHOOSEDTARGET ) {
foreach my $req ( split( /[,\s]/, $REQUIREMENTTARGET{$target} ) ) {
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
# Not found error
print "Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target}=-1;
last;
} else {
# Pas erreur ou erreur autre que programme absent
print " Found ".$REQUIREMENTTARGET{$target}."\n";
}
}
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret = `"$req" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
if (
$coderetour != 0
&& (
(
$coderetour2 == 1
&& $OS =~ /windows/
&& $ret !~ /Usage/i
)
|| ( $coderetour2 == 127 && $OS !~ /windows/ )
)
&& $PROGPATH
)
{
# Not found error, we try in PROGPATH
$ret = `"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
$REQUIREMENTTARGET{$target} =
"$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
if (
$coderetour != 0
&& (
(
$coderetour2 == 1
&& $OS =~ /windows/
&& $ret !~ /Usage/i
)
|| ( $coderetour2 == 127 && $OS !~ /windows/ )
)
)
{
# Not found error
print
"Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target} = -1;
last;
}
else {
# Pas erreur ou erreur autre que programme absent
print " Found " . $REQUIREMENTTARGET{$target} . "\n";
}
}
}
print "\n";
# Check if there is at least on target to build
# Check if there is at least one target to build
#----------------------------------------------
$nboftargetok=0;
$nboftargetneedbuildroot=0;
$nboftargetneedcvs=0;
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP')
{
$nboftargetok = 0;
$nboftargetneedbuildroot = 0;
$nboftargetneedcvs = 0;
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
if ( $target ne 'EXE' && $target ne 'EXEDOLIWAMP' ) {
$nboftargetneedbuildroot++;
}
if ($target eq 'SNAPSHOT')
{
if ( $target eq 'SNAPSHOT' ) {
$nboftargetneedcvs++;
}
$nboftargetok++;
@@ -229,178 +294,211 @@ foreach my $PROJECT (@PROJECTLIST) {
if ($nboftargetok) {
# Update CVS if required
#-----------------------
if ($nboftargetneedcvs)
{
print "Go to directory $SOURCE\n";
$olddir=getcwd();
chdir("$SOURCE");
print "Run cvs update -P -d\n";
$ret=`cvs update -P -d 2>&1`;
chdir("$olddir");
# Update CVS if required
#-----------------------
if ($nboftargetneedcvs) {
print "Go to directory $SOURCE\n";
$olddir = getcwd();
chdir("$SOURCE");
print "Run cvs update -P -d\n";
$ret = `cvs update -P -d 2>&1`;
chdir("$olddir");
}
# Update buildroot if required
#-----------------------------
if ($nboftargetneedbuildroot)
{
if (! $copyalreadydone) {
print "Delete directory $BUILDROOT\n";
$ret=`rm -fr "$BUILDROOT"`;
# Update buildroot if required
#-----------------------------
if ($nboftargetneedbuildroot) {
if ( !$copyalreadydone ) {
print "Delete directory $BUILDROOT\n";
$ret = `rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/$PROJECTLC";
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/$PROJECTLC";
print "Now, we will copy all files declared in the makepack-".$PROJECT.".conf into the directory $BUILDROOT\n";
print "Now, we will copy all files declared in the makepack-"
. $PROJECT
. ".conf into the directory $BUILDROOT\n";
$result=open(IN,"<makepack-".$PROJECT.".conf");
if (! $result) { die "Error: Can't open conf file makepack-".$PROJECT.".conf for reading.\n"; }
while(<IN>)
{
$entry=$_;
open( my $IN2, "<", "makepack-" . $PROJECT . ".conf" )
or die "Error: Can't open conf file makepack-"
. $PROJECT
. ".conf for reading.\n";
while (<$IN2>) {
$entry = $_;
if ($entry =~ /^#/) { next; } # Do not process comments
if ( $entry =~ /^#/ ) { next; } # Do not process comments
$entry =~ s/\n//;
if ($entry =~ /^!(.*)$/) # Exclude so remove file/dir
{
print "Remove $BUILDROOT/$PROJECTLC/$1\n";
$ret=`rm -fr "$BUILDROOT/$PROJECTLC/"$1`;
if ($? != 0) { die "Failed to delete a file to exclude declared into makepack-".$PROJECT.".conf file (Failed on the line ".$entry.")\n"; }
next;
}
if ( $entry =~ /^!(.*)$/ ) # Exclude so remove file/dir
{
print "Remove $BUILDROOT/$PROJECTLC/$1\n";
$ret = `rm -fr "$BUILDROOT/$PROJECTLC/"$1`;
if ( $? != 0 ) {
die
"Failed to delete a file to exclude declared into makepack-"
. $PROJECT
. ".conf file (Failed on the line "
. $entry . ")\n";
}
next;
}
$entry =~ /^(.*)\/[^\/]+/;
print "Create directory $BUILDROOT/$PROJECTLC/$1\n";
$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/$1"`;
if ($entry !~ /version\-/)
{
print "Copy $SOURCE/$entry into $BUILDROOT/$PROJECTLC/$entry\n";
$ret=`cp -pr "$SOURCE/$entry" "$BUILDROOT/$PROJECTLC/$entry"`;
if ($? != 0) { die "Failed to make copy of a file declared into makepack-".$PROJECT.".conf file (Failed on the line '".$entry."')\n"; }
}
print "Create directory $BUILDROOT/$PROJECTLC/$1\n";
$ret = `mkdir -p "$BUILDROOT/$PROJECTLC/$1"`;
if ( $entry !~ /version\-/ ) {
print
"Copy $SOURCE/$entry into $BUILDROOT/$PROJECTLC/$entry\n";
$ret =
`cp -pr "$SOURCE/$entry" "$BUILDROOT/$PROJECTLC/$entry"`;
if ( $? != 0 ) {
die
"Failed to make copy of a file declared into makepack-"
. $PROJECT
. ".conf file (Failed on the line '"
. $entry . "')\n";
}
}
}
close IN;
close $IN2;
@timearray=localtime(time());
$fulldate=($timearray[5]+1900).'-'.($timearray[4]+1).'-'.$timearray[3].' '.$timearray[2].':'.$timearray[1];
#open(VF,">$BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt");
#print "Create version file $BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt with date ".$fulldate."\n";
#$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/dev/build"`;
#print VF "Version: ".$MAJOR.".".$MINOR.($BUILD ne ''?".$BUILD":"")."\n";
#print VF "Build : ".$fulldate."\n";
#close VF;
}
print "Clean $BUILDROOT\n";
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.cache`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.git`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.project`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.settings`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/index.php`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/dev/build/html`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/documents`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/document`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.mysql`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.old`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.postgres`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf*sav*`;
if ($custom) {
$ret=`cp -r $BUILDROOT/$PROJECTLC/htdocs/custom/* $BUILDROOT/$PROJECTLC/htdocs/.`;
}
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom2`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/test`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/Thumbs.db $BUILDROOT/$PROJECTLC/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/*/Thumbs.db`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/CVS* $BUILDROOT/$PROJECTLC/*/CVS* $BUILDROOT/$PROJECTLC/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/*/CVS*`;
@timearray = localtime( time() );
$fulldate =
( $timearray[5] + 1900 ) . '-'
. ( $timearray[4] + 1 ) . '-'
. $timearray[3] . ' '
. $timearray[2] . ':'
. $timearray[1];
#open(VF,">$BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt");
#print "Create version file $BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt with date ".$fulldate."\n";
#$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/dev/build"`;
#print VF "Version: ".$MAJOR.".".$MINOR.($BUILD ne ''?".$BUILD":"")."\n";
#print VF "Build : ".$fulldate."\n";
#close VF;
}
print "Clean $BUILDROOT\n";
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.cache`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.git`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.project`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.settings`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/index.php`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/dev/build/html`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/documents`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/document`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.mysql`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.old`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.postgres`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf*sav*`;
if ($custom) {
$ret =
`cp -r $BUILDROOT/$PROJECTLC/htdocs/custom/* $BUILDROOT/$PROJECTLC/htdocs/.`;
}
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom2`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/test`;
$ret =
`rm -fr $BUILDROOT/$PROJECTLC/Thumbs.db $BUILDROOT/$PROJECTLC/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/*/Thumbs.db`;
$ret =
`rm -fr $BUILDROOT/$PROJECTLC/CVS* $BUILDROOT/$PROJECTLC/*/CVS* $BUILDROOT/$PROJECTLC/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/*/CVS*`;
}
# Build package for each target
#------------------------------
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
# Build package for each target
#------------------------------
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
print "\nBuild package for target $target\n";
print "\nBuild package for target $target\n";
if ($target eq 'TGZ') {
$NEWDESTI=$DESTI;
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
if ( $target eq 'TGZ' ) {
$NEWDESTI = $DESTI;
if ( -d $DESTI . '/../modules' ) {
$NEWDESTI = $DESTI . '/../modules';
}
print "Remove target $FILENAMETGZ.tgz...\n";
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
print "Compress $BUILDROOT/* into $FILENAMETGZ.tgz...\n";
$cmd="tar --exclude-vcs --exclude *.tgz --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" .";
$ret=`$cmd`;
if ($OS =~ /windows/i) {
print "Move $FILENAMETGZ.tgz to $NEWDESTI/$FILENAMETGZ.tgz\n";
$ret=`mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
else
{
$ret=`mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
next;
}
print "Remove target $FILENAMETGZ.tgz...\n";
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
print "Compress $BUILDROOT/* into $FILENAMETGZ.tgz...\n";
$cmd =
"tar --exclude-vcs --exclude *.tgz --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" .";
$ret = `$cmd`;
if ( $OS =~ /windows/i ) {
print
"Move $FILENAMETGZ.tgz to $NEWDESTI/$FILENAMETGZ.tgz\n";
$ret = `mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
else {
$ret = `mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
next;
}
if ($target eq 'ZIP') {
$NEWDESTI=$DESTI;
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
if ( $target eq 'ZIP' ) {
$NEWDESTI = $DESTI;
if ( -d $DESTI . '/../modules' ) {
$NEWDESTI = $DESTI . '/../modules';
}
print "Remove target $FILENAMEZIP.zip...\n";
unlink "$NEWDESTI/$FILENAMEZIP.zip";
print "Compress $FILENAMEZIP into $FILENAMEZIP.zip...\n";
print "Remove target $FILENAMEZIP.zip...\n";
unlink "$NEWDESTI/$FILENAMEZIP.zip";
print "Compress $FILENAMEZIP into $FILENAMEZIP.zip...\n";
print "Go to directory $BUILDROOT/$PROJECTLC\n";
$olddir=getcwd();
chdir("$BUILDROOT/$PROJECTLC");
$cmd= "7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip *";
print $cmd."\n";
$ret= `$cmd`;
chdir("$olddir");
print "Go to directory $BUILDROOT/$PROJECTLC\n";
$olddir = getcwd();
chdir("$BUILDROOT/$PROJECTLC");
$cmd = "7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip *";
print $cmd. "\n";
$ret = `$cmd`;
chdir("$olddir");
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
$ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
$ret=`chown $OWNER:$GROUP "$NEWDESTI/$FILENAMEZIP.zip"`;
next;
}
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
$ret =
`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
$ret = `chown $OWNER:$GROUP "$NEWDESTI/$FILENAMEZIP.zip"`;
next;
}
if ($target eq 'EXE') {
$NEWDESTI=$DESTI;
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
if ( $target eq 'EXE' ) {
$NEWDESTI = $DESTI;
if ( -d $DESTI . '/../modules' ) {
$NEWDESTI = $DESTI . '/../modules';
}
print "Remove target $FILENAMEEXE.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXE.exe";
print "Compress into $FILENAMEEXE.exe by $FILENAMEEXE.nsi...\n";
$command="\"$REQUIREMENTTARGET{$target}\" /DMUI_VERSION_DOT=$MAJOR.$MINOR.$BUILD /X\"SetCompressor bzip2\" \"$SOURCE\\dev\\build\\exe\\$FILENAME.nsi\"";
print "$command\n";
$ret=`$command`;
print "Move $FILENAMEEXE.exe to $NEWDESTI\n";
rename("$SOURCE\\dev\\build\\exe\\$FILENAMEEXE.exe","$NEWDESTI/$FILENAMEEXE.exe");
next;
}
print "Remove target $FILENAMEEXE.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXE.exe";
print "Compress into $FILENAMEEXE.exe by $FILENAMEEXE.nsi...\n";
$command =
"\"$REQUIREMENTTARGET{$target}\" /DMUI_VERSION_DOT=$MAJOR.$MINOR.$BUILD /X\"SetCompressor bzip2\" \"$SOURCE\\dev\\build\\exe\\$FILENAME.nsi\"";
print "$command\n";
$ret = `$command`;
print "Move $FILENAMEEXE.exe to $NEWDESTI\n";
rename( "$SOURCE\\dev\\build\\exe\\$FILENAMEEXE.exe",
"$NEWDESTI/$FILENAMEEXE.exe" );
next;
}
}
}
}
print "\n----- Summary -----\n";
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) {
print "Package $target not built (bad requirement).\n";
} else {
print "Package $target built successfully in $NEWDESTI\n";
}
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) {
print "Package $target not built (bad requirement).\n";
}
else {
print "Package $target built successfully in $NEWDESTI\n";
}
}
}
if (! $batch) {
print "\nPress key to finish...";
my $WAITKEY=<STDIN>;
if ( !$batch ) {
print "\nPress key to finish...";
my $WAITKEY = <STDIN>;
}
0;

View File

@@ -4,268 +4,294 @@
# \brief Script to build a theme Package for Dolibarr
# \author (c)2005-2009 Laurent Destailleur <eldy@users.sourceforge.net>
#-----------------------------------------------------------------------------
## no critic (InputOutput::ProhibitExplicitStdin)
use strict;
use warnings;
use Cwd;
use Term::ANSIColor;
$PROJECT="dolibarr";
$PROJECT = "dolibarr";
@LISTETARGET=("TGZ"); # Possible packages
%REQUIREMENTTARGET=( # Tool requirement for each package
"TGZ"=>"tar",
"ZIP"=>"7z",
"RPM"=>"rpmbuild",
"DEB"=>"dpkg-buildpackage",
"EXE"=>"makensis.exe"
@LISTETARGET = ("TGZ"); # Possible packages
%REQUIREMENTTARGET = ( # Tool requirement for each package
"TGZ" => "tar",
"ZIP" => "7z",
"RPM" => "rpmbuild",
"DEB" => "dpkg-buildpackage",
"EXE" => "makensis.exe"
);
%ALTERNATEPATH=(
"7z"=>"7-ZIP",
"makensis.exe"=>"NSIS"
%ALTERNATEPATH = (
"7z" => "7-ZIP",
"makensis.exe" => "NSIS"
);
use vars qw/ $REVISION $VERSION /;
$REVISION='1.11';
$VERSION="1.0 (build $REVISION)";
$REVISION = '1.11';
$VERSION = "1.0 (build $REVISION)";
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
$Extension = $1;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
# Detect OS type
# --------------
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
if (! $OS) {
print "$PROG.$Extension was not able to detect your OS.\n";
if ( "$^O" =~ /linux/i || ( -d "/etc" && -d "/var" && "$^O" !~ /cygwin/i ) ) {
$OS = 'linux';
$CR = '';
}
elsif ( -d "/etc" && -d "/Users" ) { $OS = 'macosx'; $CR = ''; }
elsif ( "$^O" =~ /cygwin/i || "$^O" =~ /win32/i ) {
$OS = 'windows';
$CR = "\r";
}
if ( !$OS ) {
print "$PROG.$Extension was not able to detect your OS.\n";
print "Can't continue.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
sleep 2;
exit 1;
}
# Define buildroot
# ----------------
if ($OS =~ /linux/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
if ( $OS =~ /linux/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
}
if ($OS =~ /macos/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
if ( $OS =~ /macos/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
}
if ($OS =~ /windows/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"c:/temp";
$PROGPATH=$ENV{"ProgramFiles"};
if ( $OS =~ /windows/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "c:/temp";
$PROGPATH = $ENV{"ProgramFiles"};
}
if (! $TEMP || ! -d $TEMP) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
if ( !$TEMP || !-d $TEMP ) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
print "makepack-dolibarrtheme.pl aborted.\n";
sleep 2;
exit 2;
sleep 2;
exit 2;
}
$BUILDROOT="$TEMP/dolibarr-buildroot";
$BUILDROOT = "$TEMP/dolibarr-buildroot";
my $copyalreadydone=0;
my $batch=0;
my $copyalreadydone = 0;
my $batch = 0;
print "Makepack theme version $VERSION\n";
print "Enter name of theme(s) to package (separated with space): ";
$PROJECT=<STDIN>;
$PROJECT = <STDIN>;
chomp($PROJECT);
@PROJECTLIST=split(/ /,$PROJECT);
$PROJECT=join('',@PROJECTLIST);
@PROJECTLIST = split( / /, $PROJECT );
$PROJECT = join( '', @PROJECTLIST );
# Ask and set version $MAJOR and $MINOR
print "Enter value for version: ";
$PROJVERSION=<STDIN>;
$PROJVERSION = <STDIN>;
chomp($PROJVERSION);
($MAJOR,$MINOR)=split(/\./,$PROJVERSION,2);
if ($MINOR eq '')
{
( $MAJOR, $MINOR ) = split( /\./, $PROJVERSION, 2 );
if ( $MINOR eq '' ) {
print "Enter value for minor version: ";
$MINOR=<STDIN>;
$MINOR = <STDIN>;
chomp($MINOR);
}
$FILENAME = "$PROJECT";
$FILENAMETGZ = "theme_$PROJECT-$MAJOR.$MINOR";
$FILENAMEZIP = "theme_$PROJECT-$MAJOR.$MINOR";
$FILENAME="$PROJECT";
$FILENAMETGZ="theme_$PROJECT-$MAJOR.$MINOR";
$FILENAMEZIP="theme_$PROJECT-$MAJOR.$MINOR";
if ( -d "/usr/src/redhat" ) {
if (-d "/usr/src/redhat") {
# redhat
$RPMDIR="/usr/src/redhat";
# redhat
$RPMDIR = "/usr/src/redhat";
}
if (-d "/usr/src/RPM") {
# mandrake
$RPMDIR="/usr/src/RPM";
if ( -d "/usr/src/RPM" ) {
# mandrake
$RPMDIR = "/usr/src/RPM";
}
$SOURCE="$DIR/../..";
$DESTI="$SOURCE/build";
$SOURCE = "$DIR/../..";
$DESTI = "$SOURCE/build";
# Choose package targets
#-----------------------
$target="ZIP"; # Packages uses this format
$target = "ZIP"; # Packages uses this format
if ($target) {
$CHOOSEDTARGET{uc($target)}=1;
$CHOOSEDTARGET{ uc($target) } = 1;
}
else {
my $found=0;
my $NUM_SCRIPT;
while (! $found) {
my $cpt=0;
printf(" %d - %3s (%s)\n",$cpt,"All","Need ".join(",",values %REQUIREMENTTARGET));
foreach my $target (@LISTETARGET) {
$cpt++;
printf(" %d - %3s (%s)\n",$cpt,$target,"Need ".$REQUIREMENTTARGET{$target});
}
my $found = 0;
my $NUM_SCRIPT;
while ( !$found ) {
my $cpt = 0;
printf( " %d - %3s (%s)\n",
$cpt, "All", "Need " . join( ",", values %REQUIREMENTTARGET ) );
foreach my $target (@LISTETARGET) {
$cpt++;
printf( " %d - %3s (%s)\n",
$cpt, $target, "Need " . $REQUIREMENTTARGET{$target} );
}
# Are asked to select the file to move
print "Choose one package number or several separated with space: ";
$NUM_SCRIPT=<STDIN>;
chomp($NUM_SCRIPT);
if ($NUM_SCRIPT =~ s/-//g) {
# Do not do copy
$copyalreadydone=1;
}
if ($NUM_SCRIPT !~ /^[0-$cpt\s]+$/)
{
print "This is not a valid package number list.\n";
$found = 0;
}
else
{
$found = 1;
}
}
print "\n";
if ($NUM_SCRIPT) {
foreach my $num (split(/\s+/,$NUM_SCRIPT)) {
$CHOOSEDTARGET{$LISTETARGET[$num-1]}=1;
}
}
else {
foreach my $key (@LISTETARGET) {
$CHOOSEDTARGET{$key}=1;
}
}
# Are asked to select the file to move
print "Choose one package number or several separated with space: ";
$NUM_SCRIPT = <STDIN>;
chomp($NUM_SCRIPT);
if ( $NUM_SCRIPT =~ s/-//g ) {
# Do not do copy
$copyalreadydone = 1;
}
if ( $NUM_SCRIPT !~ /^[0-$cpt\s]+$/ ) {
print "This is not a valid package number list.\n";
$found = 0;
}
else {
$found = 1;
}
}
print "\n";
if ($NUM_SCRIPT) {
foreach my $num ( split( /\s+/, $NUM_SCRIPT ) ) {
$CHOOSEDTARGET{ $LISTETARGET[ $num - 1 ] } = 1;
}
}
else {
foreach my $key (@LISTETARGET) {
$CHOOSEDTARGET{$key} = 1;
}
}
}
# Test if requirement is ok
#--------------------------
foreach my $target (keys %CHOOSEDTARGET) {
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) {
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret=`"$req" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
# Not found error, we try in PROGPATH
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
foreach my $target ( keys %CHOOSEDTARGET ) {
foreach my $req ( split( /[,\s]/, $REQUIREMENTTARGET{$target} ) ) {
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
# Not found error
print "Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target}=-1;
last;
} else {
# Pas erreur ou erreur autre que programme absent
print " Found ".$REQUIREMENTTARGET{$target}."\n";
}
}
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret = `"$req" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
if (
$coderetour != 0
&& ( ( $coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i )
|| ( $coderetour2 == 127 && $OS !~ /windows/ ) )
&& $PROGPATH
)
{
# Not found error, we try in PROGPATH
$ret = `"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
$REQUIREMENTTARGET{$target} = "$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
if (
$coderetour != 0
&& ( ( $coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i )
|| ( $coderetour2 == 127 && $OS !~ /windows/ ) )
)
{
# Not found error
print
"Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target} = -1;
last;
}
else {
# Pas erreur ou erreur autre que programme absent
print " Found " . $REQUIREMENTTARGET{$target} . "\n";
}
}
}
print "\n";
# Check if there is at least on target to build
#----------------------------------------------
$nboftargetok=0;
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
$nboftargetok++;
$nboftargetok = 0;
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
$nboftargetok++;
}
if ($nboftargetok) {
# Update buildroot
#-----------------
if (! $copyalreadydone) {
print "Delete directory $BUILDROOT\n";
$ret=`rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/htdocs";
mkdir "$BUILDROOT/htdocs/theme";
# Update buildroot
#-----------------
if ( !$copyalreadydone ) {
print "Delete directory $BUILDROOT\n";
$ret = `rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/htdocs";
mkdir "$BUILDROOT/htdocs/theme";
print "Copy $SOURCE into $BUILDROOT\n";
mkdir "$BUILDROOT";
foreach my $tmp (@PROJECTLIST)
{
$ret=`cp -pr "$SOURCE/htdocs/theme/$tmp" "$BUILDROOT/htdocs/theme"`;
print "Copy $SOURCE into $BUILDROOT\n";
mkdir "$BUILDROOT";
foreach my $tmp (@PROJECTLIST) {
$ret =
`cp -pr "$SOURCE/htdocs/theme/$tmp" "$BUILDROOT/htdocs/theme"`;
}
}
print "Clean $BUILDROOT\n";
$ret=`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/Thumbs.db`;
$ret=`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/*/CVS*`;
}
print "Clean $BUILDROOT\n";
$ret =
`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/Thumbs.db`;
$ret =
`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/*/CVS*`;
# Build package for each target
#------------------------------
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
# Build package for each target
#------------------------------
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
print "\nBuild package for target $target\n";
print "\nBuild package for target $target\n";
if ( $target eq 'TGZ' ) {
unlink $FILENAMETGZ . tgz;
print "Compress $BUILDROOT/htdocs into $FILENAMETGZ.tgz...\n";
$cmd =
"tar --exclude-vcs --exclude-from \"$DESTI/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" htdocs";
$ret = `$cmd`;
if ( $OS =~ /windows/i ) {
print "Move $FILENAMETGZ.tgz to $DESTI/$FILENAMETGZ.tgz\n";
$ret = `mv "$FILENAMETGZ.tgz" "$DESTI/$FILENAMETGZ.tgz"`;
}
next;
}
if ($target eq 'TGZ') {
unlink $FILENAMETGZ.tgz;
print "Compress $BUILDROOT/htdocs into $FILENAMETGZ.tgz...\n";
$cmd="tar --exclude-vcs --exclude-from \"$DESTI/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" htdocs";
$ret=`$cmd`;
if ($OS =~ /windows/i) {
print "Move $FILENAMETGZ.tgz to $DESTI/$FILENAMETGZ.tgz\n";
$ret=`mv "$FILENAMETGZ.tgz" "$DESTI/$FILENAMETGZ.tgz"`;
}
next;
}
if ($target eq 'ZIP') {
unlink $FILENAMEZIP.zip;
print "Compress $FILENAMETGZ into $FILENAMEZIP.zip...\n";
chdir("$BUILDROOT");
$ret=`7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip htdocs`;
if ( $target eq 'ZIP' ) {
unlink $FILENAMEZIP . zip;
print "Compress $FILENAMETGZ into $FILENAMEZIP.zip...\n";
chdir("$BUILDROOT");
$ret = `7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip htdocs`;
print "Move $FILENAMEZIP.zip to $DESTI\n";
$ret=`mv "$FILENAMEZIP.zip" "$DESTI/$FILENAMEZIP.zip"`;
next;
}
$ret = `mv "$FILENAMEZIP.zip" "$DESTI/$FILENAMEZIP.zip"`;
next;
}
}
}
}
print "\n----- Summary -----\n";
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) {
print "Package $target not built (bad requirement).\n";
} else {
print "Package $target built successfully in $DESTI\n";
}
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) {
print "Package $target not built (bad requirement).\n";
}
else {
print "Package $target built successfully in $DESTI\n";
}
}
if (! $btach) {
print "\nPress key to finish...";
my $WAITKEY=<STDIN>;
if ( !$btach ) {
print "\nPress key to finish...";
my $WAITKEY = <STDIN>;
}
0;

View File

@@ -1,7 +1,7 @@
#----------------------------------------------------------------------------
# \file dolibarr.pl
# \brief Dolibarr script install for Virtualmin Pro
# \author (c)2009-2020 Regis Houssin <regis.houssin@inodbox.com>
# \author (c)2009-2025 Regis Houssin <regis.houssin@inodbox.com>
#----------------------------------------------------------------------------
@@ -30,7 +30,15 @@ return "Regis Houssin";
# script_dolibarr_versions()
sub script_dolibarr_versions
{
return ( "14.0.5", "13.0.5", "12.0.5", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" );
return ( "22.0.3", "21.0.4", "20.0.4", "19.0.4", "18.0.8", "17.0.4", "16.0.5" );
}
sub script_dolibarr_version_desc
{
local ($ver) = @_;
my ($major_ver) = $ver =~ /^(\d+)\..*/;
return $major_ver == 22 ? "$ver (Latest)" :
$major_ver == 18 ? "$ver (LTS)" : "$ver";
}
sub script_dolibarr_release
@@ -38,6 +46,11 @@ sub script_dolibarr_release
return 2; # for mysqli fix
}
sub script_dolibarr_testable
{
return 1;
}
sub script_dolibarr_category
{
return "Commerce";
@@ -45,14 +58,23 @@ return "Commerce";
sub script_dolibarr_php_vers
{
return ( 5 );
return ( 7 );
}
sub script_dolibarr_php_vars
{
return ( [ 'memory_limit', '128M', '+' ] );
}
sub script_dolibarr_php_modules
{
local ($d, $ver, $phpver, $opts) = @_;
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
return $dbtype eq "mysql" ? ("mysql") : ("pgsql");
local @modules = ("xml", "mbstring", "gd", "iconv",
"curl", "intl", "zip");
push(@modules, ($dbtype eq "mysql" ? "mysql" : "pgsql"));
return @modules;
}
sub script_dolibarr_dbs
@@ -61,34 +83,10 @@ local ($d, $ver) = @_;
return ("mysql", "postgres");
}
# script_dolibarr_depends(&domain, version)
sub script_dolibarr_depends
sub script_dolibarr_php_fullver
{
local ($d, $ver, $sinfo, $phpver) = @_;
local @rv;
if ($ver >= 3.6) {
# Check for PHP 5.3+
local $phpv = &get_php_version($phpver || 5, $d);
if (!$phpv) {
push(@rv, "Could not work out exact PHP version");
}
elsif ($phpv < 5.3) {
push(@rv, "Dolibarr requires PHP version 5.3 or later");
}
}
if ($ver >= 12.0) {
# Check for PHP 5.6+
local $phpv = &get_php_version($phpver || 5, $d);
if (!$phpv) {
push(@rv, "Could not work out exact PHP version");
}
elsif ($phpv < 5.6) {
push(@rv, "Dolibarr requires PHP version 5.6 or later");
}
}
return @rv;
local ($d, $ver, $sinfo) = @_;
return "7.1";
}
# script_dolibarr_params(&domain, version, &upgrade-info)
@@ -195,7 +193,7 @@ local $dbpass = $dbtype eq "mysql" ? &mysql_pass($d) : &postgres_pass($d, 1);
local $dbphptype = $dbtype eq "mysql" && $version < 3.6 ? "mysql" :
$dbtype eq "mysql" ? "mysqli" : "pgsql";
local $dbhost = &get_database_host($dbtype, $d);
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
local $dberr = &check_script_db_connection($d, $dbtype, $dbname, $dbuser, $dbpass);
return (0, "Database connection failed : $dberr") if ($dberr);
# Extract tar file to temp dir and copy to target
@@ -252,7 +250,7 @@ if ($upgrade) {
&copy_source_dest_as_domain_user($d, $oldcfile, $cfile);
&copy_source_dest_as_domain_user($d, $olddocdir, $docdir);
&copy_source_dest_as_domain_user($d, $oldaltdir, $altdir);
# First page (Update database schema)
local @params = ( [ "action", "upgrade" ],
[ "versionfrom", $upgrade->{'version'} ],
@@ -260,7 +258,7 @@ if ($upgrade) {
);
local $err = &call_dolibarr_wizard_page(\@params, "upgrade", $d, $opts);
return (-1, "Dolibarr wizard failed : $err") if ($err);
# Second page (Migrate some data)
local @params = ( [ "action", "upgrade" ],
[ "versionfrom", $upgrade->{'version'} ],
@@ -268,7 +266,7 @@ if ($upgrade) {
);
local $err = &call_dolibarr_wizard_page(\@params, "upgrade2", $d, $opts);
return (-1, "Dolibarr wizard failed : $err") if ($err);
# Third page (Update version number)
local @params = ( [ "action", "upgrade" ],
[ "versionfrom", $upgrade->{'version'} ],
@@ -278,12 +276,12 @@ if ($upgrade) {
local $p = $ver >= 3.8 ? "step5" : "etape5";
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
return (-1, "Dolibarr wizard failed : $err") if ($err);
# Remove the installation directory. (deprecated)
# local $dinstall = "$opts->{'dir'}/install";
# $dinstall =~ s/\/$//;
# $out = &run_as_domain_user($d, "rm -rf ".quotemeta($dinstall));
}
else {
# First page (Db connection and config file creation)
@@ -295,6 +293,9 @@ else {
[ "db_name", $dbname ],
[ "db_user", $dbuser ],
[ "db_pass", $dbpass ],
[ "db_prefix", 'llx_' ],
[ "db_port", '3306' ],
[ "selectlang", 'en_US' ],
[ "action", "set" ],
[ "main_force_https", $opts->{'forcehttps'} ],
[ "dolibarr_main_db_character_set", $charset ],
@@ -305,13 +306,13 @@ else {
local $p = $ver >= 3.8 ? "step1" : "etape1";
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
return (-1, "Dolibarr wizard failed : $err") if ($err);
# Second page (Populate database)
local @params = ( [ "action", "set" ] );
local $p = $ver >= 3.8 ? "step2" : "etape2";
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
return (-1, "Dolibarr wizard failed : $err") if ($err);
# Third page (Add administrator account)
local @params = ( [ "action", "set" ],
[ "login", "admin" ],
@@ -322,17 +323,17 @@ else {
local $p = $ver >= 3.8 ? "step5" : "etape5";
local $err = &call_dolibarr_wizard_page(\@params, $p, $d, $opts);
return (-1, "Dolibarr wizard failed : $err") if ($err);
# Remove the installation directory (deprecated)
# local $dinstall = "$opts->{'dir'}/install";
# $dinstall =~ s/\/$//;
# $out = &run_as_domain_user($d, "rm -rf ".quotemeta($dinstall));
# Protect config file
&set_permissions_as_domain_user($d, 0644, $cfile);
&set_permissions_as_domain_user($d, 0755, $cfiledir);
}
# Return a URL for the user
local $rp = $opts->{'dir'};
$rp =~ s/^$d->{'home'}\///;
@@ -400,24 +401,32 @@ sub script_dolibarr_check_latest
{
local ($ver) = @_;
local @vers = &osdn_package_versions("dolibarr",
$ver >= 14.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 13.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 6.0 ? "dolibarr\\-(6\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 5.0 ? "dolibarr\\-(5\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 4.0 ? "dolibarr\\-(4\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.9 ? "dolibarr\\-(3\\.9\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.8 ? "dolibarr\\-(3\\.8\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.7 ? "dolibarr\\-(3\\.7\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.6 ? "dolibarr\\-(3\\.6\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.5 ? "dolibarr\\-(3\\.5\\.[0-9\\.]+)\\.tgz" :
$ver >= 2.9 ? "dolibarr\\-(2\\.9\\.[0-9\\.]+)\\.tgz" :
"dolibarr\\-(2\\.8\\.[0-9\\.]+)\\.tgz");
$ver >= 22.0 ? "dolibarr\\-(22\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 21.0 ? "dolibarr\\-(21\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 20.0 ? "dolibarr\\-(20\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 19.0 ? "dolibarr\\-(19\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 18.0 ? "dolibarr\\-(18\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 17.0 ? "dolibarr\\-(17\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 16.0 ? "dolibarr\\-(16\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 15.0 ? "dolibarr\\-(15\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 14.0 ? "dolibarr\\-(14\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 13.0 ? "dolibarr\\-(13\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 6.0 ? "dolibarr\\-(6\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 5.0 ? "dolibarr\\-(5\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 4.0 ? "dolibarr\\-(4\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.9 ? "dolibarr\\-(3\\.9\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.8 ? "dolibarr\\-(3\\.8\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.7 ? "dolibarr\\-(3\\.7\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.6 ? "dolibarr\\-(3\\.6\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.5 ? "dolibarr\\-(3\\.5\\.[0-9\\.]+)\\.tgz" :
$ver >= 2.9 ? "dolibarr\\-(2\\.9\\.[0-9\\.]+)\\.tgz" :
"dolibarr\\-(2\\.8\\.[0-9\\.]+)\\.tgz");
return "Failed to find versions" if (!@vers);
return $ver eq $vers[0] ? undef : $vers[0];
}
@@ -432,4 +441,26 @@ sub script_dolibarr_passmode
return 2;
}
sub script_dolibarr_db_conn_desc
{
my $db_conn_desc =
{ 'conf/conf.php' =>
{
'dbpass' =>
{
'func' => 'php_quotemeta',
'func_params' => 1,
'replace' => [ '\$dolibarr_main_db_pass\s*=' =>
'$dolibarr_main_db_pass=\'$$sdbpass\';' ],
},
'dbuser' =>
{
'replace' => [ '\$dolibarr_main_db_user\s*=' =>
'$dolibarr_main_db_user=\'$$sdbuser\';' ],
},
}
};
return $db_conn_desc;
}
1;

View File

@@ -150,6 +150,12 @@ parameters:
count: 3
path: ../../../htdocs/accountancy/class/bookkeeping.class.php
-
message: '#^Variable \$obj might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../../htdocs/accountancy/class/bookkeeping.class.php
-
message: '#^If condition is always false\.$#'
identifier: if.alwaysFalse
@@ -384,6 +390,12 @@ parameters:
count: 1
path: ../../../htdocs/adherents/list.php
-
message: '#^Call to function is_object\(\) with Adherent will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/adherents/messaging.php
-
message: '#^Ternary operator condition is always false\.$#'
identifier: ternary.alwaysFalse
@@ -651,7 +663,7 @@ parameters:
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
count: 4
count: 3
path: ../../../htdocs/admin/mails_templates.php
-
@@ -834,18 +846,6 @@ parameters:
count: 1
path: ../../../htdocs/admin/spip.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
count: 2
path: ../../../htdocs/admin/stocktransfer.php
-
message: '#^Variable \$setupnotempty in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
count: 1
path: ../../../htdocs/admin/stocktransfer.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
@@ -1038,18 +1038,6 @@ parameters:
count: 1
path: ../../../htdocs/admin/website.php
-
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: ../../../htdocs/admin/workflow.php
-
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
identifier: function.unresolvableReturnType
count: 1
path: ../../../htdocs/admin/workflow.php
-
message: '#^Loose comparison using \=\= between ''edit'' and ''edit'' will always evaluate to true\.$#'
identifier: equal.alwaysTrue
@@ -1068,12 +1056,6 @@ parameters:
count: 1
path: ../../../htdocs/api/class/api_setup.class.php
-
message: '#^Left side of && is always true\.$#'
identifier: booleanAnd.leftAlwaysTrue
count: 2
path: ../../../htdocs/api/class/api_setup.class.php
-
message: '#^Result of && is always false\.$#'
identifier: booleanAnd.alwaysFalse
@@ -1170,6 +1152,12 @@ parameters:
count: 1
path: ../../../htdocs/asset/card.php
-
message: '#^Property Asset\:\:\$fields \(array\<string, array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\) does not accept non\-empty\-array\<string, array\{type\: ''integer…'', label\: ''SupplierInvoice'', enabled\: ''1'', noteditable\: 1, position\: 280, notnull\: 0, visible\: 1, index\: 1, \.\.\.\}\|array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\.$#'
identifier: assign.propertyType
count: 1
path: ../../../htdocs/asset/card.php
-
message: '#^Property Asset\:\:\$date_start \(int\|string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@@ -1314,12 +1302,6 @@ parameters:
count: 1
path: ../../../htdocs/barcode/printsheet.php
-
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
count: 1
path: ../../../htdocs/blockedlog/admin/blockedlog_list.php
-
message: '#^Strict comparison using \=\=\= between ''facture'' and ''facture'' will always evaluate to true\.$#'
identifier: identical.alwaysTrue
@@ -1591,28 +1573,10 @@ parameters:
path: ../../../htdocs/categories/categorie_list.php
-
message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\> but returns array\<array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
identifier: return.type
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
identifier: identical.alwaysFalse
count: 1
path: ../../../htdocs/categories/class/categorie.class.php
-
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: ../../../htdocs/categories/class/categorie.class.php
-
message: '#^Property Categorie\:\:\$cats \(array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\>\) does not accept array\<array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
identifier: assign.propertyType
count: 2
path: ../../../htdocs/categories/class/categorie.class.php
-
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
identifier: function.unresolvableReturnType
count: 1
path: ../../../htdocs/categories/class/categorie.class.php
path: ../../../htdocs/categories/categorie_list.php
-
message: '#^If condition is always true\.$#'
@@ -1650,6 +1614,12 @@ parameters:
count: 1
path: ../../../htdocs/comm/action/card.php
-
message: '#^Property ActionComm\:\:\$contact_id \(int\) does not accept string\.$#'
identifier: assign.propertyType
count: 1
path: ../../../htdocs/comm/action/card.php
-
message: '#^Result of && is always false\.$#'
identifier: booleanAnd.alwaysFalse
@@ -1776,6 +1746,12 @@ parameters:
count: 3
path: ../../../htdocs/comm/action/index.php
-
message: '#^Property ActionComm\:\:\$datep \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 12
path: ../../../htdocs/comm/action/index.php
-
message: '#^Ternary operator condition is always true\.$#'
identifier: ternary.alwaysTrue
@@ -1806,6 +1782,12 @@ parameters:
count: 1
path: ../../../htdocs/comm/action/list.php
-
message: '#^Call to function is_object\(\) with ActionComm will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 3
path: ../../../htdocs/comm/action/list.php
-
message: '#^Loose comparison using \!\= between ''event\-current''\|''event\-future''\|''event\-past'' and '''' will always evaluate to true\.$#'
identifier: notEqual.alwaysTrue
@@ -2184,6 +2166,18 @@ parameters:
count: 1
path: ../../../htdocs/comm/mailing/targetemailing.php
-
message: '#^Call to function property_exists\(\) with Propal and ''module'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/comm/propal/agenda.php
-
message: '#^Call to function method_exists\(\) with Propal and ''setCategories'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/comm/propal/card.php
-
message: '#^Left side of && is always true\.$#'
identifier: booleanAnd.leftAlwaysTrue
@@ -2226,6 +2220,12 @@ parameters:
count: 1
path: ../../../htdocs/comm/propal/list.php
-
message: '#^Call to function method_exists\(\) with Commande and ''setCategories'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/commande/card.php
-
message: '#^Variable \$classname might not be defined\.$#'
identifier: variable.undefined
@@ -2604,6 +2604,12 @@ parameters:
count: 1
path: ../../../htdocs/compta/bank/various_payment/card.php
-
message: '#^Call to function property_exists\(\) with PaymentVarious and ''socid'' will always evaluate to false\.$#'
identifier: function.impossibleType
count: 1
path: ../../../htdocs/compta/bank/various_payment/card.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
@@ -2790,6 +2796,12 @@ parameters:
count: 1
path: ../../../htdocs/compta/facture/card-rec.php
-
message: '#^Call to function method_exists\(\) with Facture and ''setCategories'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/compta/facture/card.php
-
message: '#^Comparison operation "\<" between '''' and 0 is always true\.$#'
identifier: smaller.alwaysTrue
@@ -2802,6 +2814,12 @@ parameters:
count: 1
path: ../../../htdocs/compta/facture/card.php
-
message: '#^Loose comparison using \=\= between 3 and 3 will always evaluate to true\.$#'
identifier: equal.alwaysTrue
count: 1
path: ../../../htdocs/compta/facture/card.php
-
message: '#^Negated boolean expression is always false\.$#'
identifier: booleanNot.alwaysFalse
@@ -3528,6 +3546,12 @@ parameters:
count: 1
path: ../../../htdocs/compta/resultat/clientfourn.php
-
message: '#^Variable \$annee might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/compta/resultat/index.php
-
message: '#^Variable \$description might not be defined\.$#'
identifier: variable.undefined
@@ -4068,6 +4092,12 @@ parameters:
count: 1
path: ../../../htdocs/contact/card.php
-
message: '#^Property Contact\:\:\$roles \(array\<int, array\{id\: int, socid\: int, element\: string, source\: string, code\: string, label\: string\}\>\|null\) does not accept array\<string\>\.$#'
identifier: assign.propertyType
count: 2
path: ../../../htdocs/contact/card.php
-
message: '#^Property Societe\:\:\$typent_code \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@@ -4134,6 +4164,12 @@ parameters:
count: 6
path: ../../../htdocs/contact/list.php
-
message: '#^Call to function is_object\(\) with Contact will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/contact/messaging.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
@@ -4302,12 +4338,6 @@ parameters:
count: 1
path: ../../../htdocs/core/actions_massactions.inc.php
-
message: '#^Variable \$listofobjectthirdparties in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
count: 1
path: ../../../htdocs/core/actions_massactions.inc.php
-
message: '#^Variable \$triggername in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -4338,6 +4368,12 @@ parameters:
count: 1
path: ../../../htdocs/core/actions_setmoduleoptions.inc.php
-
message: '#^Variable \$tmpdir might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/core/actions_setmoduleoptions.inc.php
-
message: '#^Loose comparison using \=\= between ''directory'' and ''directory'' will always evaluate to true\.$#'
identifier: equal.alwaysTrue
@@ -4434,6 +4470,12 @@ parameters:
count: 1
path: ../../../htdocs/core/ajax/onlineSign.php
-
message: '#^Call to function method_exists\(\) with Propal and ''call_trigger'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/core/ajax/onlineSign.php
-
message: '#^Variable \$tva_tx in isset\(\) always exists and is not nullable\.$#'
identifier: isset.variable
@@ -5028,12 +5070,6 @@ parameters:
count: 2
path: ../../../htdocs/core/class/cleadstatus.class.php
-
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/core/class/cleadstatus.class.php
-
message: '#^Property Comment\:\:\$description \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@@ -5364,42 +5400,12 @@ parameters:
count: 1
path: ../../../htdocs/core/class/conf.class.php
-
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/core/class/cproductnature.class.php
-
message: '#^Property Cstate\:\:\$code_departement \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 4
path: ../../../htdocs/core/class/cstate.class.php
-
message: '#^Property Cstate\:\:\$name \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 2
path: ../../../htdocs/core/class/cstate.class.php
-
message: '#^Property Cstate\:\:\$nom \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 2
path: ../../../htdocs/core/class/cstate.class.php
-
message: '#^Property Cstate\:\:\$rowid \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/core/class/cstate.class.php
-
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 2
path: ../../../htdocs/core/class/ctypent.class.php
-
message: '#^Property Ctypent\:\:\$libelle \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@@ -5436,12 +5442,6 @@ parameters:
count: 4
path: ../../../htdocs/core/class/cunits.class.php
-
message: '#^Property CommonDict\:\:\$id \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 2
path: ../../../htdocs/core/class/cunits.class.php
-
message: '#^Constructor of class DolEditor has an unused parameter \$notused\.$#'
identifier: constructor.unusedParameter
@@ -5610,12 +5610,6 @@ parameters:
count: 2
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 3
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Parameter \#15 \$excludeids of method Form\:\:select_company\(\) expects array\<string\>, array\<int\> given\.$#'
identifier: argument.type
@@ -5640,54 +5634,6 @@ parameters:
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_conditions_paiements has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_demand_reason has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_invoice_subtype has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_transport_mode has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_types_fees has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_types_paiements has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Property Form\:\:\$cache_vatrates has no type specified\.$#'
identifier: missingType.property
count: 1
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
identifier: function.unresolvableReturnType
count: 3
path: ../../../htdocs/core/class/html.form.class.php
-
message: '#^Right side of && is always true\.$#'
identifier: booleanAnd.rightAlwaysTrue
@@ -5724,24 +5670,12 @@ parameters:
count: 1
path: ../../../htdocs/core/class/html.formcompany.class.php
-
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: ../../../htdocs/core/class/html.formcompany.class.php
-
message: '#^Parameter \#3 \$selected of method Form\:\:multiselectarray\(\) expects array\<string\>, array\<array\<string, int\>\|int\> given\.$#'
identifier: argument.type
count: 1
path: ../../../htdocs/core/class/html.formcompany.class.php
-
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
identifier: function.unresolvableReturnType
count: 1
path: ../../../htdocs/core/class/html.formcompany.class.php
-
message: '#^Variable \$idprof might not be defined\.$#'
identifier: variable.undefined
@@ -6510,6 +6444,12 @@ parameters:
count: 2
path: ../../../htdocs/core/lib/agenda.lib.php
-
message: '#^Variable \$s might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/core/lib/bank.lib.php
-
message: '#^Left side of && is always true\.$#'
identifier: booleanAnd.leftAlwaysTrue
@@ -7302,6 +7242,12 @@ parameters:
count: 1
path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php
-
message: '#^Variable \$fac might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/core/modules/facture/doc/pdf_sponge.modules.php
-
message: '#^Access to constant TYPE_NON on an unknown class Sprain\\SwissQrBill\\DataGroup\\Element\\PaymentReference\.$#'
identifier: class.notFound
@@ -8016,6 +7962,12 @@ parameters:
count: 2
path: ../../../htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
-
message: '#^Call to function is_array\(\) with non\-empty\-array\<int, string\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
-
message: '#^Variable \$objectdetail might not be defined\.$#'
identifier: variable.undefined
@@ -8082,12 +8034,6 @@ parameters:
count: 1
path: ../../../htdocs/core/modules/rapport/pdf_paiement.class.php
-
message: '#^Property Reception\:\:\$trueWeight \(float\|int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/core/modules/reception/doc/pdf_squille.modules.php
-
message: '#^Ternary operator condition is always false\.$#'
identifier: ternary.alwaysFalse
@@ -8292,12 +8238,6 @@ parameters:
count: 1
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
-
message: '#^Variable \$modulepart might not be defined\.$#'
identifier: variable.undefined
count: 3
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
-
message: '#^Variable \$permissiontoadd might not be defined\.$#'
identifier: variable.undefined
@@ -8316,12 +8256,6 @@ parameters:
count: 1
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
-
message: '#^Variable \$upload_dir might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../../htdocs/core/tpl/document_actions_post_headers.tpl.php
-
message: '#^Variable \$object might not be defined\.$#'
identifier: variable.undefined
@@ -8364,12 +8298,6 @@ parameters:
count: 1
path: ../../../htdocs/core/tpl/filemanager.tpl.php
-
message: '#^Variable \$limit might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../../htdocs/core/tpl/list_print_total.tpl.php
-
message: '#^Variable \$num might not be defined\.$#'
identifier: variable.undefined
@@ -8743,10 +8671,10 @@ parameters:
path: ../../../htdocs/eventorganization/conferenceorboothattendee_list.php
-
message: '#^Variable \$projectref might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../../htdocs/eventorganization/conferenceorboothattendee_list.php
message: '#^Property ExpeditionLigne\:\:\$detail_children \(array\<int, array\<int, float\|int\>\>\) on left side of \?\? is not nullable\.$#'
identifier: nullCoalesce.property
count: 1
path: ../../../htdocs/expedition/card.php
-
message: '#^Variable \$rowEnd might not be defined\.$#'
@@ -9450,6 +9378,12 @@ parameters:
count: 1
path: ../../../htdocs/fourn/class/paiementfourn.class.php
-
message: '#^Call to function method_exists\(\) with CommandeFournisseur and ''setCategories'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/fourn/commande/card.php
-
message: '#^Left side of && is always true\.$#'
identifier: booleanAnd.leftAlwaysTrue
@@ -9552,6 +9486,12 @@ parameters:
count: 1
path: ../../../htdocs/fourn/facture/card-rec.php
-
message: '#^Call to function method_exists\(\) with FactureFournisseur and ''setCategories'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/fourn/facture/card.php
-
message: '#^Comparison operation "\>" between 0 and 0 is always false\.$#'
identifier: greater.alwaysFalse
@@ -9564,6 +9504,12 @@ parameters:
count: 2
path: ../../../htdocs/fourn/facture/card.php
-
message: '#^Property FactureFournisseur\:\:\$type \(int\) does not accept string\.$#'
identifier: assign.propertyType
count: 2
path: ../../../htdocs/fourn/facture/card.php
-
message: '#^Variable \$classname might not be defined\.$#'
identifier: variable.undefined
@@ -10116,6 +10062,12 @@ parameters:
count: 1
path: ../../../htdocs/hrm/job_card.php
-
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
identifier: identical.alwaysFalse
count: 1
path: ../../../htdocs/hrm/job_list.php
-
message: '#^Comparison operation "\<" between int\<0, max\> and 0 is always false\.$#'
identifier: smaller.alwaysFalse
@@ -10140,6 +10092,12 @@ parameters:
count: 1
path: ../../../htdocs/hrm/position.php
-
message: '#^Property Position\:\:\$fields \(array\<string, array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\) does not accept non\-empty\-array\<string, array\{\}\|array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\}\>\.$#'
identifier: assign.propertyType
count: 1
path: ../../../htdocs/hrm/position_agenda.php
-
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -10734,18 +10692,6 @@ parameters:
count: 1
path: ../../../htdocs/main.inc.php
-
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: ../../../htdocs/margin/agentMargins.php
-
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
identifier: function.unresolvableReturnType
count: 1
path: ../../../htdocs/margin/agentMargins.php
-
message: '#^Ternary operator condition is always false\.$#'
identifier: ternary.alwaysFalse
@@ -11190,6 +11136,12 @@ parameters:
count: 1
path: ../../../htdocs/modulebuilder/template/myobject_list.php
-
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
identifier: identical.alwaysFalse
count: 1
path: ../../../htdocs/modulebuilder/template/myobject_list.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
@@ -11688,18 +11640,6 @@ parameters:
count: 1
path: ../../../htdocs/product/class/api_products.class.php
-
message: '#^Method Products\:\:getPurchasePrices\(\) should return array\<ProductFournisseur\> but returns object\.$#'
identifier: return.type
count: 1
path: ../../../htdocs/product/class/api_products.class.php
-
message: '#^Parameter \#1 \$object of method Products\:\:_cleanObjectDatas\(\) expects object, array\<ProductFournisseur\>\|int given\.$#'
identifier: argument.type
count: 1
path: ../../../htdocs/product/class/api_products.class.php
-
message: '#^Strict comparison using \=\=\= between 2 and 2 will always evaluate to true\.$#'
identifier: identical.alwaysTrue
@@ -11952,6 +11892,12 @@ parameters:
count: 1
path: ../../../htdocs/product/list.php
-
message: '#^Call to function is_object\(\) with Product will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/product/messaging.php
-
message: '#^Loose comparison using \=\= between ''add_customer_price'' and ''add_customer_price'' will always evaluate to true\.$#'
identifier: equal.alwaysTrue
@@ -12114,6 +12060,12 @@ parameters:
count: 4
path: ../../../htdocs/product/stats/card.php
-
message: '#^Variable \$year might not be defined\.$#'
identifier: variable.undefined
count: 3
path: ../../../htdocs/product/stats/card.php
-
message: '#^Variable \$sortfield in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -12408,6 +12360,12 @@ parameters:
count: 1
path: ../../../htdocs/product/stock/movement_list.php
-
message: '#^Variable \$productlabelselected might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../../htdocs/product/stock/movement_list.php
-
message: '#^Variable \$socid might not be defined\.$#'
identifier: variable.undefined
@@ -12426,6 +12384,12 @@ parameters:
count: 1
path: ../../../htdocs/product/stock/product.php
-
message: '#^Variable \$object in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
count: 1
path: ../../../htdocs/product/stock/product.php
-
message: '#^If condition is always true\.$#'
identifier: if.alwaysTrue
@@ -12643,22 +12607,10 @@ parameters:
path: ../../../htdocs/projet/card.php
-
message: '#^Parameter \#1 \$object of method Projects\:\:_cleanObjectDatas\(\) expects object, string given\.$#'
identifier: argument.type
count: 1
path: ../../../htdocs/projet/class/api_projects.class.php
-
message: '#^Method Tasks\:\:getRoles\(\) should return array\<int, string\> but returns list\<object\>\.$#'
message: '#^Method Projects\:\:getRoles\(\) should return array\<object\> but returns list\<string\>\.$#'
identifier: return.type
count: 1
path: ../../../htdocs/projet/class/api_tasks.class.php
-
message: '#^Parameter \#1 \$object of method Tasks\:\:_cleanObjectDatas\(\) expects object, string given\.$#'
identifier: argument.type
count: 1
path: ../../../htdocs/projet/class/api_tasks.class.php
path: ../../../htdocs/projet/class/api_projects.class.php
-
message: '#^Call to function method_exists\(\) with \$this\(Project\) and ''getLibStatut'' will always evaluate to true\.$#'
@@ -13554,6 +13506,18 @@ parameters:
count: 1
path: ../../../htdocs/public/payment/paymentok.php
-
message: '#^Call to function is_object\(\) with Adherent\|Commande\|Contrat\|Facture\|stdClass will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
path: ../../../htdocs/public/payment/paymentok.php
-
message: '#^Call to function is_object\(\) with Facture will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/public/payment/paymentok.php
-
message: '#^Call to function is_scalar\(\) with \(int\|string\) will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
@@ -13986,18 +13950,6 @@ parameters:
count: 1
path: ../../../htdocs/reception/card.php
-
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''commande'' will always evaluate to false\.$#'
identifier: equal.alwaysFalse
count: 2
path: ../../../htdocs/reception/card.php
-
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''propal'' will always evaluate to false\.$#'
identifier: equal.alwaysFalse
count: 2
path: ../../../htdocs/reception/card.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
@@ -14005,9 +13957,9 @@ parameters:
path: ../../../htdocs/reception/card.php
-
message: '#^Result of && is always false\.$#'
identifier: booleanAnd.alwaysFalse
count: 8
message: '#^Property ReceptionLineBatch\:\:\$batch \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/reception/card.php
-
@@ -14052,12 +14004,6 @@ parameters:
count: 2
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Property Reception\:\:\$size_units \(int\|string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 2
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Property Reception\:\:\$socid \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@@ -14070,30 +14016,6 @@ parameters:
count: 2
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Property Reception\:\:\$trueDepth \(float\|int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Property Reception\:\:\$trueHeight \(float\|int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Property Reception\:\:\$trueWeight \(float\|int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Property Reception\:\:\$trueWidth \(float\|int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/reception/class/reception.class.php
-
message: '#^Ternary operator condition is always true\.$#'
identifier: ternary.alwaysTrue
@@ -14190,24 +14112,6 @@ parameters:
count: 2
path: ../../../htdocs/reception/contact.php
-
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''commande'' will always evaluate to false\.$#'
identifier: equal.alwaysFalse
count: 1
path: ../../../htdocs/reception/dispatch.php
-
message: '#^Loose comparison using \=\= between ''''\|''CommandeFournisseur'' and ''propal'' will always evaluate to false\.$#'
identifier: equal.alwaysFalse
count: 1
path: ../../../htdocs/reception/dispatch.php
-
message: '#^Result of && is always false\.$#'
identifier: booleanAnd.alwaysFalse
count: 4
path: ../../../htdocs/reception/dispatch.php
-
message: '#^Variable \$objectsrc might not be defined\.$#'
identifier: variable.undefined
@@ -14670,6 +14574,12 @@ parameters:
count: 1
path: ../../../htdocs/societe/admin/societe.php
-
message: '#^Call to function is_object\(\) with Societe will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/societe/agenda.php
-
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -14874,6 +14784,12 @@ parameters:
count: 5
path: ../../../htdocs/societe/list.php
-
message: '#^Call to function is_object\(\) with Societe will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/societe/messaging.php
-
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -15205,10 +15121,16 @@ parameters:
path: ../../../htdocs/takepos/index.php
-
message: '#^Loose comparison using \=\= between 0 and 1 will always evaluate to false\.$#'
identifier: equal.alwaysFalse
message: '#^Property CommonInvoiceLine\:\:\$product_type \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../../htdocs/takepos/index.php
path: ../../../htdocs/takepos/invoice.php
-
message: '#^Property CommonObjectLine\:\:\$product \(Product\) in empty\(\) is not falsy\.$#'
identifier: empty.property
count: 2
path: ../../../htdocs/takepos/invoice.php
-
message: '#^Variable \$batch might not be defined\.$#'
@@ -15534,6 +15456,12 @@ parameters:
count: 1
path: ../../../htdocs/ticket/messaging.php
-
message: '#^Call to function is_object\(\) with User will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/user/agenda.php
-
message: '#^Call to function property_exists\(\) with User and ''admin'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
@@ -15588,12 +15516,6 @@ parameters:
count: 3
path: ../../../htdocs/user/class/user.class.php
-
message: '#^Parameter \#1 \$array of function dol_sort_array contains unresolvable type\.$#'
identifier: argument.unresolvableType
count: 1
path: ../../../htdocs/user/class/user.class.php
-
message: '#^Property User\:\:\$rights \(stdClass\) in empty\(\) is not falsy\.$#'
identifier: empty.property
@@ -15648,12 +15570,6 @@ parameters:
count: 4
path: ../../../htdocs/user/class/user.class.php
-
message: '#^Return type of call to function dol_sort_array contains unresolvable type\.$#'
identifier: function.unresolvableReturnType
count: 1
path: ../../../htdocs/user/class/user.class.php
-
message: '#^Variable \$whereforadd in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -15804,6 +15720,12 @@ parameters:
count: 1
path: ../../../htdocs/user/list.php
-
message: '#^Call to function is_object\(\) with User will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../../htdocs/user/messaging.php
-
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
@@ -15849,13 +15771,7 @@ parameters:
-
message: '#^Call to function is_object\(\) with object will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
path: ../../../htdocs/user/perms.php
-
message: '#^Variable \$menumanager might not be defined\.$#'
identifier: variable.undefined
count: 2
count: 1
path: ../../../htdocs/user/perms.php
-
@@ -16033,10 +15949,10 @@ parameters:
path: ../../../htdocs/webhook/target_list.php
-
message: '#^Loose comparison using \=\= between ''auto'' and ''auto'' will always evaluate to true\.$#'
identifier: equal.alwaysTrue
message: '#^Strict comparison using \=\=\= between array\{type\: string, label\: string, langfile\?\: string, enabled\: int\<0, 2\>\|string, position\: int, notnull\?\: int, visible\: int\<\-6, 6\>\|string, alwayseditable\?\: int\<0, 1\>\|string, \.\.\.\} and null will always evaluate to false\.$#'
identifier: identical.alwaysFalse
count: 1
path: ../../../htdocs/webportal/class/context.class.php
path: ../../../htdocs/webhook/triggerhistory_list.php
-
message: '#^Result of && is always false\.$#'
@@ -16050,24 +15966,6 @@ parameters:
count: 1
path: ../../../htdocs/webportal/class/html.formcardwebportal.class.php
-
message: '#^Comparison operation "\<\=" between int\<2, max\> and 1 is always false\.$#'
identifier: smallerOrEqual.alwaysFalse
count: 1
path: ../../../htdocs/webportal/class/html.formlistwebportal.class.php
-
message: '#^Offset ''total'' on \*NEVER\* in isset\(\) always exists and is not nullable\.$#'
identifier: isset.offset
count: 1
path: ../../../htdocs/webportal/class/html.formlistwebportal.class.php
-
message: '#^Result of && is always false\.$#'
identifier: booleanAnd.alwaysFalse
count: 1
path: ../../../htdocs/webportal/class/html.formlistwebportal.class.php
-
message: '#^Call to function is_array\(\) with list\<string\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType

View File

@@ -30,27 +30,17 @@ Alias /dolibarr /usr/share/dolibarr/htdocs
ErrorDocument 404 /public/error-404.php
# OPTIMIZE: To use gzip compressed files (for Dolibarr already compressed files).
# Note that constant MAIN_OPTIMIZE_SPEED must have a value with bit 0 set.
#AddType text/javascript .jgz
#AddEncoding gzip .jgz
# OPTIMIZE: To use gzip compression (on the fly).
# Note that you must also enable the module mod_deflate.
# You can also set this with constant MAIN_OPTIMIZE_SPEED and bit 2 set.
#TODO
# OPTIMIZE: To use cache on static pages (A259200 = 1 month).
# Note that you must also enable the module mod_expires.
#ExpiresActive On
#ExpiresByType image/x-icon A2592000
#ExpiresByType image/gif A2592000
#ExpiresByType image/png A2592000
#ExpiresByType image/jpeg A2592000
#ExpiresByType text/css A2592000
#ExpiresByType text/javascript A2592000
#ExpiresByType application/x-javascript A2592000
#ExpiresByType application/javascript A2592000
# OPTIMIZE: To use cache on static pages (A259200 = 1 month).
# Note that you must also enable the module mod_expires.
#ExpiresActive On
#ExpiresByType image/x-icon A2592000
#ExpiresByType image/gif A2592000
#ExpiresByType image/png A2592000
#ExpiresByType image/jpeg A2592000
#ExpiresByType text/css A2592000
#ExpiresByType text/javascript A2592000
#ExpiresByType application/x-javascript A2592000
#ExpiresByType application/javascript A2592000
</DirectoryMatch>

View File

@@ -1,6 +1,6 @@
This file describes changes made on external libraries after being included
in Dolibarr root.
This file describes the changes made on external libraries to fix some bugs, after they were included
in Dolibarr external vendor dir (htdocs/includes).

7
dev/lockedfiles.txt Normal file
View File

@@ -0,0 +1,7 @@
---- Locked files -----
This file is the list of the signatures of some set of files locked to block a commit if files are tried to be modified for a given version.
It is used by the CI or the script to check and guarantee that no change is done on a given scope of files.
Version Scope Signature (generated by dev/build/generate_filelist_xml.php) that must remain unchanged for this couple version/scope
x.0.0 unalterable_files 123456

3
dev/resources/dbmodel/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/dolibarr_schema.mwb.bak
/dolibarr_schema.mwb.sav.mwb
/dolibarr_schema.mwb.sav.mwb.bak

View File

@@ -33,7 +33,7 @@ do
result1=$?
if [ "x$result1" != "x0" ]
if [ "$result1" != "0" ]
then
echo "Fix the error before commit." 1>&2
exit 1
@@ -56,10 +56,10 @@ then
result2=$?
if [ "x$result2" != "x0" ]
if [ "$result2" != "0" ]
then
# Fix standard errors
if [ "x$AUTOFIX" != "x0" ]
if [ "$AUTOFIX" != "0" ]
then
# shellcheck disable=2086,2090
"${DIRPHPCS}phpcbf" -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES

View File

@@ -45,7 +45,7 @@ function save_db_cache() (
cd "${TRAVIS_BUILD_DIR}/htdocs/install" || exit 1
# Get the target version from the version.inc.php file
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9.]*\\).*/\\1/p" ../version.inc.php) ; echo $target_version
target_version=$(sed -n "s/.*define('DOL_\\(MAJOR_\\)\\?VERSION',[[:space:]]*'\\([0-9.]*\\).*/\\2/p" ../version.inc.php) ; echo $target_version
# Default in case that failed
target_version=${target_version:=22.0.0}

View File

@@ -0,0 +1,33 @@
README (English)
--------------------------------
##############
RapidAPI
##############
RapidAPI for Mac is a full-featured HTTP client that let's you test and describe the APIs you build or consume.
It has a beautiful native macOS interface to compose requests, inspect server responses, generate client code and export API definitions.
https://paw.cloud/
@@@
(@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%
@@@@@@, @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,
@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(@@@@@@( @@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@. /@@@@@@@@@@@@@@@@@(
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@. @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ /@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@# @@@@@@@@@@@ @@@@@@@@@@@@&
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@/
@@@@@@@@@@@@@@@@@@@@@@@@@@& .@@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@/
(@@@@@@@@@@@@@@@@@@@@@@@ .@@@@@@@@@@@ &@@@@@@@@@@@@@@@(
@@@@@ @@@@@ .@@@@@@@@@@@ @@@@@@@@@@@*

View File

@@ -11,351 +11,386 @@
# Pour les cles autoincrement: rowid integer AUTO_INCREMENT PRIMARY KEY,
# Mettre les index dans fichier.key.sql
#------------------------------------------------------------------------------
## no critic (InputOutput::ProhibitExplicitStdin,InputOutput::RequireBriefOpen)
use Data::Dumper;
use Getopt::Long;
use strict;
use warnings;
use vars qw/ $DIR $PROG $Extension $SOURCE $DESTI %filelist $stop /;
# command line options
my( $opt_debug, $opt_help);
my ( $opt_debug, $opt_help );
# general values
my ($out, $size);
my ( $out, $size );
# variables for constructing pre-create-table entities
my $create_sql=''; # if empty we are not making a create statement
my $create_index=''; # if empty we are not making a create statement
my %enum_datafield=(); # holds enumeration choices
my (@column_values,$enum_column, $seq);
my $table="";
my $create_sql = ''; # if empty we are not making a create statement
my $create_index = ''; # if empty we are not making a create statement
my %enum_datafield = (); # holds enumeration choices
my ( @column_values, $enum_column, $seq );
my $table = "";
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
$Extension = $1;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
$SOURCE="$DIR/install/mysql/tables";
$DESTI="$DIR/install/pgsql/tables";
$SOURCE = "$DIR/install/mysql/tables";
$DESTI = "$DIR/install/pgsql/tables";
# Recherche tous les fichiers .sql
opendir(DIR, $SOURCE);
foreach my $file (readdir(DIR)) {
if ($file =~ /\.sql$/ && -f "$SOURCE/$file") {
print "Found file $file\n";
$filelist{$file}=1;
}
}
closedir(DIR);
opendir( my $dir, $SOURCE );
foreach my $file ( readdir($dir) ) {
if ( $file =~ /\.sql$/ && -f "$SOURCE/$file" ) {
print "Found file $file\n";
$filelist{$file} = 1;
}
}
closedir($dir);
# Boucle sur tous les fichiers de SOURCE
#---------------------------------------
foreach my $file (keys %filelist) {
foreach my $file ( keys %filelist ) {
$ARGV[0]="$SOURCE/$file";
$ARGV[1]="$DESTI/$file";
local $ARGV[0] = "$SOURCE/$file";
local $ARGV[1] = "$DESTI/$file";
print "Convert file $ARGV[0] into $ARGV[1]\n";
print "Convert file $ARGV[0] into $ARGV[1]\n";
# MySQL to PostgreSQL dump file converter
#
# For usage: perl mysql2pgsql.perl --help
#
# homepage: http://www.rot13.org/~dpavlin/projects.html
# 1999-12-15 DbP -- Dobrica Pavlinusic <dpavlin@rot13.org>
# 1999-12-26 DbP don't make serial from auto_increment, create all manually
# (to set start value right)
# 2000-01-11 DbP now creates sequences with correct value
# 2000-04-25 DbP import into CVS (at cvs.linux.hr)
# 2001-01-29 tpo -- Tomas Pospisek <tpo@sourcepole.ch>:
# 1) make script comply to usage:
# 2) make script output to STDOUT instead of STERR
# 3) change verbosity behaveour
# 4) add debug option
# see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql
# 2003-12-16 jsp -- Joe Speigle <joe.speigle@jklh.us>:
# converts: s/\) *Type=MyISAM;/);/i, enum data type -> references,
# auto_increment->sequences
# 2004-01-13 jsp -- moved project to gborg; both the above declined ownership
# 2004-06-29 converts: year(4), year(2)
# homepage: gborg.postgresql.org
# MySQL to PostgreSQL dump file converter
#
# For usage: perl mysql2pgsql.perl --help
#
# homepage: http://www.rot13.org/~dpavlin/projects.html
# 1999-12-15 DbP -- Dobrica Pavlinusic <dpavlin@rot13.org>
# 1999-12-26 DbP don't make serial from auto_increment, create all manually
# (to set start value right)
# 2000-01-11 DbP now creates sequences with correct value
# 2000-04-25 DbP import into CVS (at cvs.linux.hr)
# 2001-01-29 tpo -- Tomas Pospisek <tpo@sourcepole.ch>:
# 1) make script comply to usage:
# 2) make script output to STDOUT instead of STERR
# 3) change verbosity behaveour
# 4) add debug option
# see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql
# 2003-12-16 jsp -- Joe Speigle <joe.speigle@jklh.us>:
# converts: s/\) *Type=MyISAM;/);/i, enum data type -> references,
# auto_increment->sequences
# 2004-01-13 jsp -- moved project to gborg; both the above declined ownership
# 2004-06-29 converts: year(4), year(2)
# homepage: gborg.postgresql.org
GetOptions("debug", "help");
GetOptions( "debug", "help" );
my $DEBUG = $opt_debug || 0;
my $HELP = $opt_help || 0;
my $DEBUG = $opt_debug || 0;
my $HELP = $opt_help || 0;
if ( ($HELP) || !defined( $ARGV[0] ) || !defined( $ARGV[1] ) ) {
print
"Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n";
print "\t* OPTIONS\n";
print
"\t--verbose tees to pg_dump_file.sql and STDOUT during conversion\n";
print "\t--debug does ?? \n";
print "\t--help prints this message \n";
print "\t* REQUIRED ARGUMENTS\n";
if ( defined( $ARGV[0] ) ) {
print "\tmysql_dump_file.sql ($ARGV[0])\n";
}
else {
print "\tmysql_dump_file.sql (undefined)\n";
}
if ( defined( $ARGV[1] ) ) {
print "\tpg_dump_file.sql ($ARGV[1])\n";
}
else {
print "\tpg_dump_file.sql (undefined)\n";
}
exit 1;
}
if (($HELP) || ! defined($ARGV[0]) || ! defined($ARGV[1])) {
print "Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n";
print "\t* OPTIONS\n";
print "\t--verbose tees to pg_dump_file.sql and STDOUT during conversion\n";
print "\t--debug does ?? \n";
print "\t--help prints this message \n";
print "\t* REQUIRED ARGUMENTS\n";
if (defined ($ARGV[0])) {
print "\tmysql_dump_file.sql ($ARGV[0])\n";
} else {
print "\tmysql_dump_file.sql (undefined)\n";
}
if (defined ($ARGV[1])) {
print "\tpg_dump_file.sql ($ARGV[1])\n";
} else {
print "\tpg_dump_file.sql (undefined)\n";
}
exit 1;
}
open( my $in, "<", "$ARGV[0]" )
|| die "can't open mysql dump file $ARGV[0]";
open( my $out, ">", "$ARGV[1]" ) || die "can't open pg dump file $ARGV[1]";
print $out "-- Generated by $PROG\n";
print $out "-- (c) 2004, PostgreSQL Inc.\n";
print $out "-- (c) 2005, Laurent Destailleur.\n";
print $out "\n";
open(IN,"<$ARGV[0]") || die "can't open mysql dump file $ARGV[0]";
open(OUT,">$ARGV[1]") || die "can't open pg dump file $ARGV[1]";
print OUT "-- Generated by $PROG\n";
print OUT "-- (c) 2004, PostgreSQL Inc.\n";
print OUT "-- (c) 2005, Laurent Destailleur.\n";
print OUT "\n";
# Output for create table and create index
sub output_create {
# Output for create table and create index
sub output_create {
# If command ends with "xxx,);", we change to "xxx);"
$create_sql =~ s/,(\s*)\);/$1\);/m;
# If command ends with "xxx, -- yyy );", we change to "xxx -- yyy);"
$create_sql =~ s/,(\s*\-\-[^\)\n]*)(\s*)\);/$1\n\);/m;
# If command ends with "xxx,);", we change to "xxx);"
$create_sql =~ s/,(\s*)\);/$1\);/m;
print OUT $create_sql;
if ($create_index) {
print OUT "\n";
print OUT $create_index;
}
}
# If command ends with "xxx, -- yyy );", we change to "xxx -- yyy);"
$create_sql =~ s/,(\s*\-\-[^\)\n]*)(\s*)\);/$1\n\);/m;
# Reset when moving from each "create table" to "insert" part of dump
sub reset_vars() {
$create_sql="";
$create_index="";
%enum_datafield=();
$enum_column='';
}
print $out $create_sql;
if ($create_index) {
print $out "\n";
print $out $create_index;
}
return;
}
# Reset when moving from each "create table" to "insert" part of dump
sub reset_vars() {
$create_sql = "";
$create_index = "";
%enum_datafield = ();
$enum_column = '';
return;
}
# Boucle sur contenu fichier source
#----------------------------------
while(<IN>) {
# Boucle sur contenu fichier source
#----------------------------------
while (<$in>) {
# comments or empty lines
if (/^-- \$Id/) {
$_ =~ s/\$//g;
print OUT $_;
if (/^-- \$Id/) {
$_ =~ s/\$//g;
print $out $_;
next;
}
# comments or empty lines
if (/^#/ || /^$/ || /^--/) {
print OUT $_;
next;
}
if (/^USE\s*([^;]*);/) {
print OUT "\\c ". $1;
next;
}
if ($create_sql ne "") { # we are inside create table statement so let's process datatypes
if ( /^#/ || /^$/ || /^--/ ) {
print $out $_;
next;
}
if (/^USE\s*([^;]*);/) {
print $out "\\c " . $1;
next;
}
if ( $create_sql ne "" )
{ # we are inside create table statement so let's process datatypes
if (/\);/i) { # end of create table sequence
$create_sql =~ s/,$//g; # strip last , inside create table
&output_create;
&reset_vars();
next;
# LDR Added "innodb" and "engine"
}
elsif (/(ISAM|innodb)/i) { # end of create table sequence
s/\) *type=(MyISAM|innodb);/);/i;
s/\) *engine=(MyISAM|innodb);/);/i;
$create_sql =~ s/,$//g; # strip last , inside create table
$create_sql .= $_;
&output_create;
&reset_vars();
next;
}
if (/\);/i) { # end of create table sequence
$create_sql =~ s/,$//g; # strip last , inside create table
&output_create;
&reset_vars();
next;
# enum -> check
if (/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i) {
$enum_column=$1;
$enum_datafield{$enum_column}=$2; # 'abc','def', ...
my $suite=$3;
my $maxlength=0;
foreach my $enum (split(',',$enum_datafield{$enum_column})) {
$enum =~ s/[\"\']//g;
if ($maxlength<length($enum)) { $maxlength=length($enum); }
}
$enum_datafield{$enum_column} =~ s/\"/\'/g;
$_ = qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~;
# int, auto_increment -> serial
} elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) {
$seq = qq~${table}_${1}_seq~;
s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig;
$create_sql.=$_;
next;
# int type conversion
} elsif (/(\w*)int\(\d+\)/i) {
$size=$1;
$size =~ tr [A-Z] [a-z];
if ($size eq "tiny" || $size eq "small") {
$out = "int2";
} elsif ($size eq "big") {
$out = "int8";
} else {
$out = "int4";
}
s/\w*int\(\d+\)/$out/g;
}
# tinyint -> smallint
elsif (/tinyint/i) {
s/tinyint/smallint/g;
}
# LDR Added "innodb" and "engine"
}
elsif (/(ISAM|innodb)/i) { # end of create table sequence
s/\) *type=(MyISAM|innodb);/);/i;
s/\) *engine=(MyISAM|innodb);/);/i;
$create_sql =~ s/,$//g; # strip last , inside create table
$create_sql .= $_;
&output_create;
&reset_vars();
next;
}
# nuke unsigned
s/(int\w+|smallint)\s+unsigned/$1/gi;
# enum -> check
if (
/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i
)
{
$enum_column = $1;
$enum_datafield{$enum_column} = $2; # 'abc','def', ...
my $suite = $3;
my $maxlength = 0;
foreach my $enum ( split( ',', $enum_datafield{$enum_column} ) )
{
$enum =~ s/[\"\']//g;
if ( $maxlength < length($enum) ) {
$maxlength = length($enum);
}
}
$enum_datafield{$enum_column} =~ s/\"/\'/g;
$_ =
qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~;
# int, auto_increment -> serial
}
elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) {
$seq = qq~${table}_${1}_seq~;
s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig;
$create_sql .= $_;
next;
# blob -> text
s/\w*blob/text/gi;
# int type conversion
}
elsif (/(\w*)int\(\d+\)/i) {
$size = $1;
$size =~ tr [A-Z] [a-z];
if ( $size eq "tiny" || $size eq "small" ) {
$out = "int2";
}
elsif ( $size eq "big" ) {
$out = "int8";
}
else {
$out = "int4";
}
s/\w*int\(\d+\)/$out/g;
}
# tinytext/mediumtext -> text
s/tinytext/text/gi;
s/mediumtext/text/gi;
# tinyint -> smallint
elsif (/tinyint/i) {
s/tinyint/smallint/g;
}
# char -> varchar
# PostgreSQL would otherwise pad with spaces as opposed
# to MySQL! Your user interface may depend on this!
s/(\s+)char/${1}varchar/gi;
# nuke unsigned
s/(int\w+|smallint)\s+unsigned/$1/gi;
# nuke date representation (not supported in PostgreSQL)
s/datetime default '[^']+'/datetime/i;
s/date default '[^']+'/datetime/i;
s/time default '[^']+'/datetime/i;
# blob -> text
s/\w*blob/text/gi;
# change not null datetime field to null valid ones
# (to support remapping of "zero time" to null
s/datetime not null/datetime/i;
s/datetime/timestamp/i;
# tinytext/mediumtext -> text
s/tinytext/text/gi;
s/mediumtext/text/gi;
# nuke size of timestamp
s/timestamp\([^)]*\)/timestamp/i;
# char -> varchar
# PostgreSQL would otherwise pad with spaces as opposed
# to MySQL! Your user interface may depend on this!
s/(\s+)char/${1}varchar/gi;
# double -> numeric
s/^double/numeric/i;
s/(\s*)double/${1}numeric/i;
# nuke date representation (not supported in PostgreSQL)
s/datetime default '[^']+'/datetime/i;
s/date default '[^']+'/datetime/i;
s/time default '[^']+'/datetime/i;
# float -> numeric
s/^float/numeric/i;
s/(\s*)float/${1}numeric/i;
# change not null datetime field to null valid ones
# (to support remapping of "zero time" to null
s/datetime not null/datetime/i;
s/datetime/timestamp/i;
# unique key(field1,field2)
if (/unique key\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique key\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql.=$_;
next;
}
# unique index(field1,field2)
if (/unique index\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique index\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql.=$_;
next;
}
# nuke size of timestamp
s/timestamp\([^)]*\)/timestamp/i;
# unique key [name] (field)
if (/unique key\s*(\w*)\s*\((\w+)\)/i) {
s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname=($1?"$1":"idx_${table}_$2");
$create_sql.=$_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# unique index [name] (field)
if (/unique index\s*(\w*)\s*\((\w+)\)/i) {
s/unique index\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname=($1?"$1":"idx_${table}_$2");
$create_sql.=$_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# unique (field) et unique (field1, field2 ...)
if (/unique\s*\(([\w,\s]+)\)/i) {
s/unique\s*\(([\w,\s]+)\)/UNIQUE\($1\)/i;
my $fieldlist="$1";
my $idxname="idx_${table}_${fieldlist}";
$idxname =~ s/\W/_/g; $idxname =~ tr/_/_/s;
$create_sql.=$_;
$create_index .= "CREATE INDEX $idxname ON $table ($fieldlist);\n";
next;
}
# double -> numeric
s/^double/numeric/i;
s/(\s*)double/${1}numeric/i;
# index(field)
if (/index\s*(\w*)\s*\((\w+)\)/i) {
my $idxname=($1?"$1":"idx_${table}_$2");
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# float -> numeric
s/^float/numeric/i;
s/(\s*)float/${1}numeric/i;
# primary key
if (/\bkey\b/i && !/^\s+primary key\s+/i) {
s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i; # hack off name of the non-primary key
}
# unique key(field1,field2)
if (/unique key\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique key\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql .= $_;
next;
}
# key(xxx)
if (/key\s*\((\w+)\)/i) {
my $idxname="idx_${table}_$1";
$create_index .= "CREATE INDEX $idxname ON $table ($1);\n";
next;
}
# unique index(field1,field2)
if (/unique index\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique index\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql .= $_;
next;
}
# Quote column names
s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if (!/\bkey\b/i);
# unique key [name] (field)
if (/unique key\s*(\w*)\s*\((\w+)\)/i) {
s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
$create_sql .= $_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# Remap columns with names of existing system attribute
if (/"oid"/i) {
s/"oid"/"_oid"/g;
print STDERR "WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue.";
my $wait=<STDIN>;
}
s/oid/_oid/i if (/key/i && /oid/i); # fix oid in key
$create_sql.=$_;
} # END of if ($create_sql ne "") i.e. were inside create table statement so processed datatypes
else { # not inside create table
#---- fix data in inserted data: (from MS world)
# FIX: disabled for now
if (00 && /insert into/i) {
s!\x96!-!g; # --
s!\x93!"!g; # ``
s!\x94!"!g; # ''
s!\x85!... !g; # \ldots
s!\x92!`!g;
}
# unique index [name] (field)
if (/unique index\s*(\w*)\s*\((\w+)\)/i) {
s/unique index\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
$create_sql .= $_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# fix dates '0000-00-00 00:00:00' (should be null)
s/'0000-00-00 00:00:00'/null/gi;
s/'0000-00-00'/null/gi;
s/'00:00:00'/null/gi;
s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/;
# unique (field) et unique (field1, field2 ...)
if (/unique\s*\(([\w,\s]+)\)/i) {
s/unique\s*\(([\w,\s]+)\)/UNIQUE\($1\)/i;
my $fieldlist = "$1";
my $idxname = "idx_${table}_${fieldlist}";
$idxname =~ s/\W/_/g;
$idxname =~ tr/_/_/s;
$create_sql .= $_;
$create_index .=
"CREATE INDEX $idxname ON $table ($fieldlist);\n";
next;
}
if (/create\s+table\s+(\w+)/i) {
$create_sql = $_;
/create\s*table\s*(\w+)/i;
$table=$1 if (defined($1));
} else {
print OUT $_;
}
} # end of if inside create_table
} # END while(<IN>)
# index(field)
if (/index\s*(\w*)\s*\((\w+)\)/i) {
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
close IN;
close OUT;
# primary key
if ( /\bkey\b/i && !/^\s+primary key\s+/i ) {
s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i
; # hack off name of the non-primary key
}
# key(xxx)
if (/key\s*\((\w+)\)/i) {
my $idxname = "idx_${table}_$1";
$create_index .= "CREATE INDEX $idxname ON $table ($1);\n";
next;
}
# Quote column names
s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if ( !/\bkey\b/i );
# Remap columns with names of existing system attribute
if (/"oid"/i) {
s/"oid"/"_oid"/g;
print STDERR
"WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue.";
my $wait = <STDIN>;
}
s/oid/_oid/i if ( /key/i && /oid/i ); # fix oid in key
$create_sql .= $_;
} # END of if ($create_sql ne "") i.e. were inside create table statement so processed datatypes
else { # not inside create table
#---- fix data in inserted data: (from MS world)
# FIX: disabled for now
if ( 00 && /insert into/i ) {
s!\x96!-!g; # --
s!\x93!"!g; # ``
s!\x94!"!g; # ''
s!\x85!... !g; # \ldots
s!\x92!`!g;
}
# fix dates '0000-00-00 00:00:00' (should be null)
s/'0000-00-00 00:00:00'/null/gi;
s/'0000-00-00'/null/gi;
s/'00:00:00'/null/gi;
s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/;
if (/create\s+table\s+(\w+)/i) {
$create_sql = $_;
/create\s*table\s*(\w+)/i;
$table = $1 if ( defined($1) );
}
else {
print $out $_;
}
} # end of if inside create_table
} # END while(<IN>)
close $in;
close $out;
}
print "\n";
print "Build ".(scalar keys %filelist)." file(s).\n";
print "Build " . ( scalar keys %filelist ) . " file(s).\n";
print "\n";
print "Press a key to finish...\n";
$stop=<STDIN>;
$stop = <STDIN>;
0;

View File

@@ -12,19 +12,24 @@ cp "$0" /tmp/github_commits_perversion.sh
TEMP_DIR=/tmp/git
DOL_GIT="$TEMP_DIR/dolibarr"
if ! git rev-parse ; then
echo "Delete $TEMP_DIR"
echo "/tmp/git/dolibarr is not a git repo. Delete $TEMP_DIR"
rm -fr "$TEMP_DIR"
echo "Create '$TEMP_DIR' and cd to it"
mkdir "$TEMP_DIR"
mkdir -p "$TEMP_DIR"
cd "$TEMP_DIR" || exit
git clone https://github.com/Dolibarr/dolibarr.git
cd "${DOL_GIT}" || exit
else
echo "/tmp/git/dolibarr is a git repo."
mkdir -p ${DOL_GIT}
if [ -r "${DOL_GIT}" ] ; then
echo git worktree remove "${DOL_GIT}"
git worktree remove "${DOL_GIT}"
rm -rf "${DOL_GIT}" >& /dev/null
fi
echo git worktree add --force "${DOL_GIT}" develop
git worktree add --force "${DOL_GIT}" develop
cd "$DOL_GIT" || exit
git pull
@@ -36,7 +41,10 @@ Releases=("3.9" "4.0" "5.0" "6.0" "7.0" "8.0" "9.0" "10.0" "11.0" "12.0" "13.0"
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9]*\\.[0-9]*\\).*/\\1/p" htdocs/version.inc.php)
# Default target version in case getting it from filefunc.inc failed
target_version=${target_version:=20.0}
target_version=${target_version:=23}
echo "Last version to test target_version = $target_version";
# Setup loop to append required versions
target_major=${target_version%%.*}
@@ -90,8 +98,9 @@ do
done
# Clean up git directory if it is a worktree
if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ] ; then
cd "$TEMP_DIR" || exit
git -C "$DOL_GIT" worktree remove "$DOL_GIT"
fi
#if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ] ; then
# cd "$TEMP_DIR" || exit
# git -C "$DOL_GIT" worktree remove "$DOL_GIT"
#fi
exit

View File

@@ -1,8 +1,10 @@
#!/bin/bash
# Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
# Borrowed from https://gist.github.com/lgiraudel/6065155
# Inplace mode added by Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
# shellcheck disable=2003,2006,2034,2046,2086,2166,2268
# shellcheck disable=2003,2006,2034,2046,2086,2166,2268,2327,2328
PROGNAME=${0##*/}
INPUT=''

View File

@@ -10,13 +10,13 @@
return [
// # Issue statistics:
// PhanUndeclaredProperty : 420+ occurrences
// PhanTypeMismatchProperty : 100+ occurrences
// PhanTypeMismatchProperty : 95+ occurrences
// PhanTypeMismatchArgument : 65+ occurrences
// PhanUndeclaredGlobalVariable : 60+ occurrences
// PhanTypeMismatchArgumentNullable : 20+ occurrences
// PhanTypeInvalidDimOffset : 15+ occurrences
// PhanTypeMismatchDimFetch : 10+ occurrences
// PhanUndeclaredMethod : 7 occurrences
// PhanUndeclaredMethod : 6 occurrences
// PhanTypeArraySuspiciousNull : 5 occurrences
// PhanTypeExpectedObjectPropAccess : 5 occurrences
// PhanPluginDuplicateArrayKey : 4 occurrences
@@ -76,7 +76,6 @@ return [
'htdocs/core/ajax/selectobject.php' => ['PhanTypeMismatchArgumentNullable'],
'htdocs/core/class/CMailFile.class.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/class/canvas.class.php' => ['PhanUndeclaredMethod'],
'htdocs/core/class/ccountry.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/cgenericdic.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/commonobject.class.php' => ['PhanParamTooMany', 'PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/core/class/commonpeople.class.php' => ['PhanUndeclaredProperty'],
@@ -146,7 +145,6 @@ return [
'htdocs/core/tpl/objectline_view.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/core/tpl/passwordreset.tpl.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/core/tpl/resource_view.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php' => ['PhanUndeclaredProperty'],
'htdocs/delivery/class/delivery.class.php' => ['PhanUndeclaredProperty'],
'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanUndeclaredProperty'],
@@ -165,7 +163,7 @@ return [
'htdocs/fourn/class/fournisseur.commande.class.php' => ['PhanUndeclaredProperty'],
'htdocs/fourn/commande/card.php' => ['PhanUndeclaredProperty'],
'htdocs/fourn/facture/card-rec.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/fourn/facture/card.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'],
'htdocs/fourn/facture/card.php' => ['PhanTypeMismatchArgument'],
'htdocs/fourn/facture/rapport.php' => ['PhanTypeMismatchArgument'],
'htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/holiday/card_group.php' => ['PhanTypeMismatchArgument'],
@@ -255,11 +253,9 @@ return [
'htdocs/user/class/usergroup.class.php' => ['PhanUndeclaredProperty'],
'htdocs/variants/tpl/productattributevalueline_edit.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/variants/tpl/productattributevalueline_view.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/viewimage.php' => ['PhanUndeclaredMethod'],
'htdocs/webhook/class/target.class.php' => ['PhanUndeclaredMethod'],
'htdocs/webhook/target_card.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/webportal/admin/setup.php' => ['PhanTypeMismatchArgument'],
'htdocs/webportal/class/html.formcardwebportal.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/webportal/class/html.formlistwebportal.class.php' => ['PhanUndeclaredProperty'],
'htdocs/webportal/class/webportalpropal.class.php' => ['PhanUndeclaredProperty'],
'htdocs/webservices/server_project.php' => ['PhanUndeclaredProperty'],

View File

@@ -1,20 +1,22 @@
<?php
/* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*/
/* PHP 7.0 */
$finder = (new PhpCsFixer\Finder())
->in(__DIR__)
->exclude([
'core/includes',
'custom',
'documents',
'doctemplates',
'vendor',
'install/doctemplates',
'htdocs/custom',
'htdocs/includes',
'htdocs/install/doctemplates',
])
->notPath('vendor');
->in(__DIR__)
->exclude([
'core/includes',
'custom',
'documents',
'doctemplates',
'vendor',
'install/doctemplates',
'htdocs/custom',
'htdocs/includes',
'htdocs/install/doctemplates',
])
->notPath('vendor');
/* PHP 7.4+ */
@@ -43,8 +45,11 @@ return (new PhpCsFixer\Config())
// So we use target PHP70 for the moment.
'@PHP70Migration' => true,
//'@PHP71Migration' => true,
// Avoid adding public to const (incompatible with PHP 7.0):
'visibility_required' => ['elements'=>['property', 'method']],
// Avoid adding public to const (incompatible with PHP 7.0):
'visibility_required' => ['elements' => ['property', 'method']],
// Replace deprecated 'visibility_required'
'modifier_keywords' => ['elements' => ['property', 'method']],
//'strict_param' => true,
//'array_syntax' => ['syntax' => 'short'],
@@ -59,5 +64,4 @@ return (new PhpCsFixer\Config())
->setIndent("\t")
// All files MUST use the Unix LF line ending only
// https://www.php-fig.org/psr/psr-12/#22-files
->setLineEnding("\n")
;
->setLineEnding("\n");

View File

@@ -108,6 +108,16 @@ ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT
ACCOUNTING_VAT_PAY_ACCOUNT
ACCOUNTING_VAT_SOLD_ACCOUNT
ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT
ACCOUNTING_LT1_BUY_ACCOUNT
ACCOUNTING_LT2_BUY_ACCOUNT
ACCOUNTING_LT1_BUY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT2_BUY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT1_PAY_ACCOUNT
ACCOUNTING_LT2_PAY_ACCOUNT
ACCOUNTING_LT1_PAY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT2_PAY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT1_SOLD_ACCOUNT
ACCOUNTING_LT2_SOLD_ACCOUNT
AI_API_MODEL_AUDIO
AI_API_MODEL_IMAGE

View File

@@ -130,7 +130,6 @@ AvailabilityType
BAN
BI
BOMs
Back
Bad value for email, email was not verified by Google
Bad value for returned userinfo[aud]
Bad value for returned userinfo[exp]. Token expired.

View File

@@ -46,7 +46,7 @@ $ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used

View File

@@ -488,11 +488,11 @@ if ($action != 'export') {
// print_liste_field_titre("Type", $_SERVER['PHP_SELF'], "t.type", "", $param, "", $sortfield, $sortorder);
//}
if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder);
print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", "", $param, 'class="right"', $sortfield, $sortorder);
}
print_liste_field_titre("AccountingDebit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder);
print_liste_field_titre("AccountingCredit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder);
print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder);
print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
// Hook fields
$parameters = array('param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);

View File

@@ -50,7 +50,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php';
$langs->loadLangs(array("accountancy", "bills", "compta"));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
$type = GETPOST('type', 'alpha');
@@ -682,7 +682,7 @@ if ($action == 'create') {
print '<table class="nobordernopadding centpercent"><tr><td>';
print $langs->trans('Ref');
print '</td>';
if ($action != 'editref') {
if ($action != 'editref' && empty($object->date_validation)) {
print '<td class="right">';
if ($permissiontoadd && $numRefModel === 'mod_bookkeeping_neon') {
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editref&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
@@ -691,7 +691,7 @@ if ($action == 'create') {
}
print '</tr></table>';
print '</td><td>';
if ($action == 'editref') {
if ($action == 'editref' && empty($object->date_validation)) {
print '<form name="setref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -717,14 +717,14 @@ if ($action == 'create') {
print '</td>';
if ($action != 'editdocref') {
print '<td class="right">';
if ($permissiontoadd) {
if ($permissiontoadd && empty($object->date_validation)) {
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdocref&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
}
print '</td>';
}
print '</tr></table>';
print '</td><td>';
if ($action == 'editdocref') {
if ($action == 'editdocref' && empty($object->date_validation)) {
print '<form name="setdocref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -750,14 +750,14 @@ if ($action == 'create') {
print '</td>';
if ($action != 'editdate') {
print '<td class="right">';
if ($permissiontoadd) {
if ($permissiontoadd && empty($object->date_validation)) {
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdate&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'</a>';
}
print '</td>';
}
print '</tr></table>';
print '</td><td colspan="3">';
if ($action == 'editdate') {
if ($action == 'editdate' && empty($object->date_validation)) {
print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -783,14 +783,14 @@ if ($action == 'create') {
print '</td>';
if ($action != 'editjournal') {
print '<td class="right">';
if ($permissiontoadd) {
if ($permissiontoadd && empty($object->date_validation)) {
print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editjournal&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
}
print '</td>';
}
print '</tr></table>';
print '</td><td>';
if ($action == 'editjournal') {
if ($action == 'editjournal' && empty($object->date_validation)) {
print '<form name="setjournal" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@@ -851,7 +851,7 @@ if ($action == 'create') {
print '<tr>';
print '<td class="titlefield">' . $langs->trans("DateExport") . '</td>';
print '<td>';
print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : '&nbsp;';
print $object->date_export ? img_picto($langs->trans("TransactionExportDesc"), 'fa-file-export', 'class="pictofixedwidth opacitymedium"').dol_print_date($object->date_export, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
@@ -859,7 +859,7 @@ if ($action == 'create') {
print '<tr>';
print '<td class="titlefield">' . $langs->trans("DateValidation") . '</td>';
print '<td>';
print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : '&nbsp;';
print $object->date_validation ? img_picto($langs->trans("TransactionBlockedLockedDesc"), 'fa-lock', 'class="pictofixedwidth opacitymedium"').dol_print_date($object->date_validation, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
@@ -966,21 +966,23 @@ if ($action == 'create') {
// List of movements
print load_fiche_titre($langs->trans("ListeMvts"), '', '');
print '<form action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
if (empty($object->date_validation)) {
print '<form action="' . $_SERVER["PHP_SELF"] . '?piece_num=' . ((int) $object->piece_num) . '" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
}
print '<input type="hidden" name="token" value="' . newToken() . '">';
print '<input type="hidden" name="doc_date" value="' . $object->doc_date . '">' . "\n";
print '<input type="hidden" name="doc_type" value="' . $object->doc_type . '">' . "\n";
print '<input type="hidden" name="doc_ref" value="' . $object->doc_ref . '">' . "\n";
print '<input type="hidden" name="ref" value="' . $object->ref . '">' . "\n";
print '<input type="hidden" name="code_journal" value="' . $object->code_journal . '">' . "\n";
print '<input type="hidden" name="fk_doc" value="' . $object->fk_doc . '">' . "\n";
print '<input type="hidden" name="fk_docdet" value="' . $object->fk_docdet . '">' . "\n";
print '<input type="hidden" name="mode" value="' . $mode . '">' . "\n";
print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
print '<input type="hidden" name="type" value="' . $type . '">';
}
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="doc_date" value="'.$object->doc_date.'">'."\n";
print '<input type="hidden" name="doc_type" value="'.$object->doc_type.'">'."\n";
print '<input type="hidden" name="doc_ref" value="'.$object->doc_ref.'">'."\n";
print '<input type="hidden" name="ref" value="'.$object->ref.'">'."\n";
print '<input type="hidden" name="code_journal" value="'.$object->code_journal.'">'."\n";
print '<input type="hidden" name="fk_doc" value="'.$object->fk_doc.'">'."\n";
print '<input type="hidden" name="fk_docdet" value="'.$object->fk_docdet.'">'."\n";
print '<input type="hidden" name="mode" value="'.$mode.'">'."\n";
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<input type="hidden" name="type" value="'.$type.'">';
if (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
@@ -1005,7 +1007,7 @@ if ($action == 'create') {
print "</tr>\n";
// Add an empty line if there is not yet
if (!empty($object->linesmvt[0])) {
if (!empty($object->linesmvt[0]) && empty($object->date_validation)) {
$tmpline = $object->linesmvt[0];
if (!empty($tmpline->numero_compte)) {
$line = new BookKeepingLine($db);
@@ -1017,7 +1019,7 @@ if ($action == 'create') {
$total_debit += $line->debit;
$total_credit += $line->credit;
if ($action == 'update' && $line->id == $id) {
if ($action == 'update' && $line->id == $id && empty($object->date_validation)) {
print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
print '<!-- td columns in edit mode -->';
print '<td>';
@@ -1044,7 +1046,7 @@ if ($action == 'create') {
print '<input type="submit" class="button" name="update" value="'.$langs->trans("Update").'">';
print '</td>';
print "</tr>\n";
} elseif (empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) {
} elseif ((empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) && empty($object->date_validation)) {
if (($action == "" || $action == 'add') && $permissiontoadd) {
print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
print '<!-- td columns in add mode -->';

View File

@@ -1272,6 +1272,12 @@ while ($i < min($num, $limit)) {
$object->piece_num = $line->piece_num;
$object->ref = $line->ref;
print $object->getNomUrl(1, '', 0, '', 1);
if (!empty($line->date_export)) {
print img_picto($langs->trans("DateExport").": ".dol_print_date($line->date_export, 'dayhour')." (".$langs->trans("TransactionExportDesc").")", 'fa-file-export', 'class="paddingleft pictofixedwidth opacitymedium"');
}
if (!empty($line->date_validation)) {
print img_picto($langs->trans("DateValidation").": ".dol_print_date($line->date_validation, 'dayhour')." (".$langs->trans("TransactionBlockedLockedDesc").")", 'fa-lock', 'class="paddingleft pictofixedwidth opacitymedium"');
}
print '</td>';
if (!$i) {
$totalarray['nbfield']++;

View File

@@ -1420,6 +1420,12 @@ while ($i < min($num, $limit)) {
$object->piece_num = $line->piece_num;
$object->ref = $line->ref;
print $object->getNomUrl(1, '', 0, '', 1);
if (!empty($line->date_export)) {
print img_picto($langs->trans("DateExport").": ".dol_print_date($line->date_export, 'dayhour')." (".$langs->trans("TransactionExportDesc").")", 'fa-file-export', 'class="paddingleft pictofixedwidth opacitymedium"');
}
if (!empty($line->date_validation)) {
print img_picto($langs->trans("DateValidation").": ".dol_print_date($line->date_validation, 'dayhour')." (".$langs->trans("TransactionBlockedLockedDesc").")", 'fa-lock', 'class="paddingleft pictofixedwidth opacitymedium"');
}
print '</td>';
if (!$i) {
$totalarray['nbfield']++;

View File

@@ -1016,7 +1016,7 @@ class AccountancyExport
$tab['affaire'] = str_repeat(' ', 10);
$tab['quantity1'] = str_repeat(' ', 10);
$tab['num_piece2'] = str_pad(self::trunc((string) $line->piece_num, 8), 8);
$tab['devis'] = str_pad($conf->currency, 3);
$tab['devis'] = str_pad(getDolCurrency(), 3);
$tab['code_journal2'] = str_pad(self::trunc($line->code_journal, 3), 3);
$tab['filler3'] = str_repeat(' ', 3);

View File

@@ -759,7 +759,7 @@ class AccountingJournal extends CommonObject
}
// Build SQL - Customer invoices closed by discount
$sql = "SELECT f.rowid, f.ref, f.datef, f.fk_soc, f.total_ttc";
$sql = "SELECT f.rowid, f.ref, f.datef, f.date_closing, f.fk_soc, f.total_ttc";
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
$sql .= " WHERE f.entity IN (".getEntity('invoice', 0).')'; // We don't share object for accountancy, we use source object sharing
$sql .= " AND f.fk_statut > 0";
@@ -770,19 +770,21 @@ class AccountingJournal extends CommonObject
}
$sql .= " AND f.close_code = 'discount_vat'";
if ($date_start && $date_end) {
$sql .= " AND f.datef >= '".$this->db->idate($date_start)."' AND f.datef <= '".$this->db->idate($date_end)."'";
$sql .= " AND f.date_closing >= '".$this->db->idate($date_start)."' AND f.date_closing <= '".$this->db->idate($date_end)."'";
}
if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
$sql .= " AND f.datef >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
$sql .= " AND f.date_closing >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
}
if ($in_bookkeeping == 'already') {
$sql .= " AND EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid AND ab.piece_num LIKE 'OD-ESC-%')";
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid";
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
} elseif ($in_bookkeeping == 'notyet') {
$sql .= " AND NOT EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid AND ab.piece_num LIKE 'OD-ESC-%')";
$sql .= " WHERE ab.doc_type = 'customer_invoice' AND ab.fk_doc = f.rowid";
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
}
$sql .= " ORDER BY f.datef";
$sql .= " ORDER BY f.date_closing";
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
@@ -816,7 +818,7 @@ class AccountingJournal extends CommonObject
// Discounted amount including tax
$paid = (float) price2num($invoice_static->getSommePaiement(), 'MT');
$usedcn = (float) price2num($invoice_static->getSumOfCreditNotesUsed(), 'MT');
$usedcn = (float) price2num($invoice_static->getSumCreditNotesUsed(), 'MT');
$useddep = (float) price2num($invoice_static->getSumDepositsUsed(), 'MT');
$ttc_inv = (float) price2num($invoice_static->total_ttc, 'MT');
$escompte_ttc = (float) price2num(max(0, $ttc_inv - $paid - $usedcn - $useddep), 'MT');
@@ -825,7 +827,8 @@ class AccountingJournal extends CommonObject
}
$bookkeeping_static = new BookKeeping($this->db);
$label_discount = $bookkeeping_static->accountingLabelForOperation($customer_static->getNomUrl(1, 'customer'), $invoice_static->ref, $langs->trans('DiscountGranted'));
$thirdpartyname = (string) $customer_static->name;
$label_discount = $bookkeeping_static->accountingLabelForOperation($thirdpartyname, $invoice_static->ref, $langs->trans('DiscountGranted'));
// Distribution including VAT by rate
$ttcByRate = array();
@@ -853,7 +856,9 @@ class AccountingJournal extends CommonObject
'blocks' => array(),
);
$docdate = $this->db->jdate($obj->datef);
$closingdate = !empty($obj->date_closing) ? $obj->date_closing : $obj->datef;
$docdate = $this->db->jdate($closingdate);
$docdate_fmt = dol_print_date($docdate, 'day');
$sumTTC = 0.0;
@@ -1063,7 +1068,7 @@ class AccountingJournal extends CommonObject
}
// SQL - Supplier invoices closed by discount
$sql = "SELECT ff.rowid, ff.ref, ff.datef, ff.fk_soc, ff.total_ttc";
$sql = "SELECT ff.rowid, ff.ref, ff.datef, ff.date_closing, ff.fk_soc, ff.total_ttc";
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff";
$sql .= " WHERE ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND ff.fk_statut > 0";
@@ -1074,19 +1079,21 @@ class AccountingJournal extends CommonObject
}
$sql .= " AND ff.close_code = 'discount_vat'";
if ($date_start && $date_end) {
$sql .= " AND ff.datef >= '".$this->db->idate($date_start)."' AND ff.datef <= '".$this->db->idate($date_end)."'";
$sql .= " AND ff.date_closing >= '".$this->db->idate($date_start)."' AND ff.date_closing <= '".$this->db->idate($date_end)."'";
}
if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
$sql .= " AND ff.datef >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
$sql .= " AND ff.date_closing >= '".$this->db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
}
if ($in_bookkeeping == 'already') {
$sql .= " AND EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid AND ab.piece_num LIKE 'OD-ESC-FRS-%')";
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid";
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
} elseif ($in_bookkeeping == 'notyet') {
$sql .= " AND NOT EXISTS (SELECT 1 FROM ".MAIN_DB_PREFIX."accounting_bookkeeping ab";
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid AND ab.piece_num LIKE 'OD-ESC-FRS-%')";
$sql .= " WHERE ab.doc_type = 'supplier_invoice' AND ab.fk_doc = ff.rowid";
$sql .= " AND ab.code_journal = '".$this->db->escape($this->code)."')";
}
$sql .= " ORDER BY ff.datef";
$sql .= " ORDER BY ff.date_closing";
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
@@ -1120,7 +1127,7 @@ class AccountingJournal extends CommonObject
// Discounted amount including tax
$paid = (float) price2num($invoicesupplier_static->getSommePaiement(), 'MT');
$usedcn = (float) price2num($invoicesupplier_static->getSumOfCreditNotesUsed(), 'MT');
$usedcn = (float) price2num($invoicesupplier_static->getSumCreditNotesUsed(), 'MT');
$useddep = (float) price2num($invoicesupplier_static->getSumDepositsUsed(), 'MT');
$ttc_inv = (float) price2num($invoicesupplier_static->total_ttc, 'MT');
$escompte_ttc = (float) price2num(max(0, $ttc_inv - $paid - $usedcn - $useddep), 'MT');
@@ -1129,7 +1136,8 @@ class AccountingJournal extends CommonObject
}
$bookkeeping_static = new BookKeeping($this->db);
$label_discount = $bookkeeping_static->accountingLabelForOperation($supplier_static->getNomUrl(1, 'supplier'), $invoicesupplier_static->ref, $langs->trans('DiscountReceived'));
$thirdpartyname = (string) $supplier_static->name;
$label_discount = $bookkeeping_static->accountingLabelForOperation($thirdpartyname, $invoicesupplier_static->ref, $langs->trans('DiscountReceived'));
// Distribution including VAT by rate
$ttcByRate = array();
@@ -1157,7 +1165,9 @@ class AccountingJournal extends CommonObject
'blocks' => array(),
);
$docdate = $this->db->jdate($obj->datef);
$closingdate = !empty($obj->date_closing) ? $obj->date_closing : $obj->datef;
$docdate = $this->db->jdate($closingdate);
$docdate_fmt = dol_print_date($docdate, 'day');
$sumTTC = 0.0;

View File

@@ -471,7 +471,7 @@ if ($result) {
}
// User
if (!empty($arrayfields['u.login']['checked'])) {
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", "", $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
}
// Expensereport

View File

@@ -524,7 +524,7 @@ if ($result) {
}
// User
if (!empty($arrayfields['u.login']['checked'])) {
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER['PHP_SELF'], "u.login", "", $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
}
// Expensereport

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
@@ -30,15 +30,6 @@
* \brief Page with expense reports journal
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -47,6 +38,14 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
// Load translation files required by the page
$langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "trips", "errors"));
@@ -356,6 +355,16 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
if (!$errorforline) {
foreach ($tabht[$key] as $k => $mt) {
if ($mt) {
if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch(0, $k, true);
$conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
} else {
$accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
}
$account_label = $accountingaccount->label;
// get compte id and label
if ($accountingaccount->fetch(0, $k, true)) {
$bookkeeping = new BookKeeping($db);
@@ -370,9 +379,10 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
$bookkeeping->subledger_label = '';
$bookkeeping->numero_compte = $k;
$bookkeeping->label_compte = $accountingaccount->label;
$bookkeeping->label_compte = $account_label;
$bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($userstatic->name, '', $account_label);
$bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($userstatic->name, '', $accountingaccount->label);
$bookkeeping->montant = $mt;
$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
$bookkeeping->debit = ($mt > 0) ? $mt : 0;
@@ -418,12 +428,12 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
foreach ($arrayofvat[$key] as $k => $mt) {
if ($mt) {
if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch(0, $k, true);
$conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
$conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
} else {
$accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
$accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
}
$account_label = $accountingaccount->label;

View File

@@ -666,7 +666,14 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
foreach ($arrayofvat[$key] as $k => $mt) {
if ($mt) {
$accountingaccount->fetch(0, $k, true); // TODO Use a cache for label
if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch(0, $k, true);
$conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
} else {
$accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
}
$label_account = $accountingaccount->label;
$bookkeeping = new BookKeeping($db);

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
@@ -747,7 +747,14 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
foreach ($arrayofvat[$key] as $k => $mt) {
if ($mt) {
$accountingaccount->fetch(0, $k, true); // TODO Use a cache for label
if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch(0, $k, true);
$conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
} else {
$accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
}
$label_account = $accountingaccount->label;
$bookkeeping = new BookKeeping($db);
@@ -808,7 +815,14 @@ if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'b
if (isset($tabrevenuestamp[$key]) && is_array($tabrevenuestamp[$key])) {
foreach ($tabrevenuestamp[$key] as $k => $mt) {
if ($mt) {
$accountingaccount->fetch(0, $k, true); // TODO Use a cache for label
if (empty($conf->cache['accountingaccountincurrententity_rs'][$k])) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch(0, $k, true);
$conf->cache['accountingaccountincurrententity_rs'][$k] = $accountingaccount;
} else {
$accountingaccount = $conf->cache['accountingaccountincurrententity_rs'][$k];
}
$label_account = $accountingaccount->label;
$bookkeeping = new BookKeeping($db);

View File

@@ -93,7 +93,9 @@ if ($action == 'update') {
$res = dolibarr_set_const($db, "MEMBER_MIN_AMOUNT", $minamount, 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "MEMBER_COUNTERS_ARE_PUBLIC", $publiccounters, 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "MEMBER_SKIP_TABLE", $showtable ? 0 : 1, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "skip -> show"
$res = dolibarr_set_const($db, "MEMBER_HIDE_VOTE_ALLOWED", $showvoteallowed ? 0 : 1, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "hide -> show"
if (GETPOSTISSET('MEMBER_HIDE_VOTE_ALLOWED')) {
$res = dolibarr_set_const($db, "MEMBER_HIDE_VOTE_ALLOWED", $showvoteallowed ? 0 : 1, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "hide -> show"
}
$res = dolibarr_set_const($db, "MEMBER_NEWFORM_PAYONLINE", $payonline, 'chaine', 0, '', $conf->entity);
if ($forcetype < 0) {
$res = dolibarr_del_const($db, "MEMBER_NEWFORM_FORCETYPE", $conf->entity);
@@ -225,6 +227,24 @@ if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
print '<td></td>';
print "</tr>\n";
// Show the table of all available membership types. If not, show a form (as the default was for Dolibarr <=16.0)
$skiptable = getDolGlobalInt('MEMBER_SKIP_TABLE');
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("MembersShowMembershipTypesTable");
print '</td><td>';
print $form->selectyesno("MEMBER_SHOW_TABLE", (int) !$skiptable, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
print "</td></tr>\n";
// Show "vote allowed" setting for membership types
if (!$skiptable) {
$hidevoteallowed = getDolGlobalInt('MEMBER_HIDE_VOTE_ALLOWED');
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("MembersShowVotesAllowed");
print '</td><td>';
print $form->selectyesno("MEMBER_SHOW_VOTE_ALLOWED", (int) !$hidevoteallowed, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
print "</td></tr>\n";
}
// Force Type
$adht = new AdherentType($db);
print '<tr class="oddeven drag" id="trforcetype"><td>';
@@ -272,22 +292,6 @@ if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
print $form->selectyesno("MEMBER_COUNTERS_ARE_PUBLIC", getDolGlobalInt('MEMBER_COUNTERS_ARE_PUBLIC'), 1, false, 0, 1);
print "</td></tr>\n";
// Show the table of all available membership types. If not, show a form (as the default was for Dolibarr <=16.0)
$skiptable = getDolGlobalInt('MEMBER_SKIP_TABLE');
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("MembersShowMembershipTypesTable");
print '</td><td>';
print $form->selectyesno("MEMBER_SHOW_TABLE", (int) !$skiptable, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
print "</td></tr>\n";
// Show "vote allowed" setting for membership types
$hidevoteallowed = getDolGlobalInt('MEMBER_HIDE_VOTE_ALLOWED');
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("MembersShowVotesAllowed");
print '</td><td>';
print $form->selectyesno("MEMBER_SHOW_VOTE_ALLOWED", (int) !$hidevoteallowed, 1, false, 0, 1); // Reverse the logic "hide -> show" for retrocompatibility
print "</td></tr>\n";
// Jump to an online payment page
print '<tr class="oddeven" id="trpayment"><td>';
print $langs->trans("MEMBER_NEWFORM_PAYONLINE");

View File

@@ -30,12 +30,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -43,10 +37,33 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
// Load translation files required by the page
$langs->loadLangs(array('companies', 'members'));
$action = GETPOST('action', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : getDolDefaultContextPage(__FILE__);
if (GETPOSTISARRAY('actioncode')) {
$actioncode = GETPOST('actioncode', 'array:alpha', 3);
if (!count($actioncode)) {
$actioncode = '0';
}
} else {
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
}
$search_rowid = GETPOST('search_rowid');
$search_agenda_label = GETPOST('search_agenda_label');
$search_complete = GETPOST('search_complete');
$search_dateevent_start = GETPOSTDATE('dateevent_start');
$search_dateevent_end = GETPOSTDATE('dateevent_end');
// Get Parameters
$id = GETPOSTINT('id') ? GETPOSTINT('id') : GETPOSTINT('rowid');
@@ -66,20 +83,9 @@ if (!$sortfield) {
$sortfield = 'a.datep,a.id';
}
if (!$sortorder) {
$sortorder = 'DESC';
$sortorder = 'DESC,DESC';
}
if (GETPOST('actioncode', 'array')) {
$actioncode = GETPOST('actioncode', 'array', 3);
if (!count($actioncode)) {
$actioncode = '0';
}
} else {
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
}
$search_rowid = GETPOST('search_rowid');
$search_agenda_label = GETPOST('search_agenda_label');
// Get object canvas (By default, this is not defined, so standard usage of dolibarr)
$objcanvas = null;
@@ -104,7 +110,7 @@ if ($result > 0) {
* Actions
*/
$parameters = array('id'=>$id, 'objcanvas'=>$objcanvas);
$parameters = array('id' => $id, 'objcanvas' => $objcanvas);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
@@ -122,6 +128,7 @@ if (empty($reshook)) {
$actioncode = '';
$search_rowid = '';
$search_agenda_label = '';
$search_complete = '';
}
}
@@ -172,6 +179,8 @@ if ($object->id > 0) {
print '</div>';
print '<div class="clearboth"></div>';
print dol_get_fiche_end();
@@ -187,7 +196,7 @@ if ($object->id > 0) {
$newcardbutton .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
if (isModEnabled('agenda')) {
$newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/comm/action/card.php', ['action' => 'create', 'backtopage' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'origin' => 'member', 'originid' => $id])]));
$newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/comm/action/card.php', ['action' => 'create', 'origin' => 'member', 'originid' => $id, 'backtopage' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'origin' => 'member', 'originid' => $id])]));
}
if (isModEnabled('agenda') && ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) {
@@ -195,12 +204,35 @@ if ($object->id > 0) {
$param = '&id='.$id;
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.$contextpage;
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.$limit;
$param .= '&limit='.((int) $limit);
}
if ($search_rowid) {
$param .= '&search_rowid='.urlencode($search_rowid);
}
if ($actioncode !== '' && $actioncode !== '-1') {
$param .= '&actioncode='.urlencode($actioncode);
}
if ($search_agenda_label) {
$param .= '&search_agenda_label='.urlencode($search_agenda_label);
}
if ($search_complete != '') {
$param .= '&search_complete='.urlencode($search_complete);
}
if ($search_dateevent_start != '') {
$param .= '&dateevent_startyear='.GETPOSTINT('dateevent_startyear');
$param .= '&dateevent_startmonth='.GETPOSTINT('dateevent_startmonth');
$param .= '&dateevent_startday='.GETPOSTINT('dateevent_startday');
}
if ($search_dateevent_end != '') {
$param .= '&dateevent_endyear='.GETPOSTINT('dateevent_endyear');
$param .= '&dateevent_endmonth='.GETPOSTINT('dateevent_endmonth');
$param .= '&dateevent_endday='.GETPOSTINT('dateevent_endday');
}
// Try to know count of actioncomm from cache
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
$cachekey = 'count_events_member_'.$object->id;
$nbEvent = dol_getcache($cachekey);
@@ -210,15 +242,16 @@ if ($object->id > 0) {
$titlelist = $langs->trans("Actions").(is_numeric($nbEvent) ? '<span class="opacitymedium colorblack paddingleft">('.$nbEvent.')</span>' : '');
}
print_barre_liste($titlelist, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $newcardbutton, '', 0, 1, 0);
print_barre_liste($titlelist, 0, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', 0, -1, '', 0, $newcardbutton, '', 0, 1, 0);
// List of all actions
$filters = array();
$filters['search_agenda_label'] = $search_agenda_label;
$filters['search_rowid'] = $search_rowid;
$filters['search_complete'] = $search_complete; // Can be 'na', '0', '100', '50'
// TODO Replace this with same code than into list.php
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder);
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module);
}
}

View File

@@ -1914,16 +1914,16 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Login
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
print '<tr><td class="titlefield">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
}
// Type
print '<tr><td class="titlefield">'.$langs->trans("Type").'</td>';
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td>';
print '<td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
// Morphy
print '<tr><td>'.$langs->trans("MemberNature").'</td>';
print '<td class="valeur" >'.$object->getmorphylib('', 1).'</td>';
print '<td class="valeur">'.$object->getmorphylib('', 1).'</td>';
print '</tr>';
// Company
@@ -1988,13 +1988,13 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Tags / Categories
if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
print '<tr><td>'.$langs->trans("Categories").'</td>';
print '<td colspan="2">';
print '<td>';
print $form->showCategories($object->id, Categorie::TYPE_MEMBER, 1);
print '</td></tr>';
}
// Birth Date
print '<tr><td class="titlefield">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
print '<tr><td class="titlefieldmiddle">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
// Default language
if (getDolGlobalInt('MAIN_MULTILANGS')) {
@@ -2095,7 +2095,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Send
if (empty($user->socid)) {
if (Adherent::STATUS_VALIDATED == $object->status) {
print '<a class="butAction" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle">'.$langs->trans('SendMail').'</a>'."\n";
print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
}
}

View File

@@ -106,7 +106,7 @@ class Adherent extends CommonObject
public $civility_code;
/**
* @var int
* @var string Human readable civility
*/
public $civility;
@@ -210,7 +210,7 @@ class Adherent extends CommonObject
public $datevalid;
/**
* @var string gender
* @var ?string gender
*/
public $gender;
@@ -268,7 +268,7 @@ class Adherent extends CommonObject
public $first_subscription_date_end;
/**
* @var int|string|null date
* @var null|float|string amount
*/
public $first_subscription_amount;
@@ -288,7 +288,7 @@ class Adherent extends CommonObject
public $last_subscription_date_end;
/**
* @var null|float|string date, null until set
* @var null|float|string amount, null until set
*/
public $last_subscription_amount;
@@ -810,7 +810,9 @@ class Adherent extends CommonObject
// Clean parameters
$this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
$this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
$this->gender = trim($this->gender);
if (isset($this->gender)) {
$this->gender = trim($this->gender);
}
// $this->address = ($this->address ? $this->address : $this->address);
// $this->zip = ($this->zip ? $this->zip : $this->zip);
// $this->town = ($this->town ? $this->town : $this->town);
@@ -2162,6 +2164,7 @@ class Adherent extends CommonObject
// Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
//if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
$invoice->fetch($invoice->id); // Reload invoice object data
$invoice->generateDocument($invoice->model_pdf, $outputlangs);
}
}
@@ -3097,10 +3100,10 @@ class Adherent extends CommonObject
/**
* Load type info information in the member object
* Load type info information in the member object
*
* @param int $id Id of member to load
* @return void
* @param int $id Id of member to load
* @return void
*/
public function info($id)
{
@@ -3200,7 +3203,7 @@ class Adherent extends CommonObject
global $conf;
//Only valid members
if ($this->statut != self::STATUS_VALIDATED) {
if ($this->status != self::STATUS_VALIDATED) {
return false;
}
if (!$this->datefin) {

View File

@@ -674,7 +674,7 @@ class AdherentType extends CommonObject
* Return the array of all amounts per membership type id
*
* @param int $status Filter on status of type
* @return array<int,string> Array of membership type
* @return array<int,float> Array of membership type
*/
public function amountByType($status = null)
{
@@ -696,7 +696,7 @@ class AdherentType extends CommonObject
while ($i < $nump) {
$obj = $this->db->fetch_object($resql);
$amountbytype[$obj->rowid] = $obj->amount;
$amountbytype[$obj->rowid] = (float) $obj->amount;
$i++;
}
}

View File

@@ -544,9 +544,12 @@ class Members extends DolibarrApi
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
* Clean sensible object datas
* @phpstan-template T
*
* @param Object $object Object to clean
* @return Object Object with cleaned properties
* @phpstan-param T $object
* @phpstan-return T
*/
public function _cleanObjectDatas($object)
{

View File

@@ -289,9 +289,12 @@ class MembersTypes extends DolibarrApi
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
* Clean sensible object datas
* @phpstan-template T
*
* @param Object $object Object to clean
* @return Object Object with cleaned properties
* @phpstan-param T $object
* @phpstan-return T
*/
protected function _cleanObjectDatas($object)
{

View File

@@ -1130,7 +1130,7 @@ if (!empty($arrayfields['d.lastname']['checked'])) {
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.gender']['checked'])) {
print_liste_field_titre($arrayfields['d.gender']['label'], $_SERVER['PHP_SELF'], 'd.gender', $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.gender']['label'], $_SERVER['PHP_SELF'], 'd.gender', '', $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.company']['checked'])) {

View File

@@ -147,11 +147,11 @@ if (is_object($adht)) {
}
// Type
print '<tr><td>'.$langs->trans("Type").'</td>';
print '<tr><td class="titlefield">'.$langs->trans("Type").'</td>';
print '<td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
// Morphy
print '<tr><td class="titlefield">'.$langs->trans("MemberNature").'</td>';
print '<tr><td>'.$langs->trans("MemberNature").'</td>';
print '<td class="valeur" >'.$object->getmorphylib('', 1).'</td>';
print '</tr>';

View File

@@ -50,7 +50,7 @@ $id = GETPOSTINT('rowid') ? GETPOSTINT('rowid') : GETPOSTINT('id');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'partnershipcard'; // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha');
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');

View File

@@ -26,9 +26,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -36,6 +33,8 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
$graphwidth = 700;
$mapratio = 0.5;
@@ -191,9 +190,9 @@ foreach ($data as $val) {
print '<td>'.$memberstatic->getmorphylib($val['label']).'</td>';
print '<td class="right">'.$nb.'</td>';
print '<td class="right">'.$nbactive.'</td>';
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour').'</td>';
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour', 'auto', null, false, 1).'</td>';
print '<td class="right">'.$nbsubscriptions.'</td>';
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour').'</td>';
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour', 'auto', null, false, 1).'</td>';
print '</tr>';
}

View File

@@ -26,11 +26,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -38,12 +33,16 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
$graphwidth = DolGraph::getDefaultGraphSizeForStats('width', '700');
$mapratio = 0.5;
$graphheight = round($graphwidth * $mapratio);
$mode = GETPOST('mode') ? GETPOST('mode') : '';
$mode = GETPOST('mode');
// Security check
@@ -54,7 +53,7 @@ if ($user->socid > 0) {
restrictedArea($user, 'adherent', '', '', 'cotisation');
$year = (int) dol_print_date(dol_now('gmt'), "%Y", 'gmt');
$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
$startyear = $year - (getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))) : 2);
$endyear = $year;
// Load translation files required by the page
@@ -322,8 +321,8 @@ if ($mode) {
print '<td class="center">'.$val['label2'].'</td>';
}
print '<td class="right">'.$val['nb'].'</td>';
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour').'</td>';
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour').'</td>';
print '<td class="center">'.dol_print_date($val['lastdate'], 'dayhour', 'auto', null, false, 1).'</td>';
print '<td class="center">'.dol_print_date($val['lastsubscriptiondate'], 'dayhour', 'auto', null, false, 1).'</td>';
print '</tr>';
}

View File

@@ -31,6 +31,14 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
@@ -41,15 +49,6 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
$langs->loadLangs(array("companies", "bills", "members", "users", "mails", 'other'));
$action = GETPOST('action', 'aZ09');
@@ -61,7 +60,7 @@ $id = GETPOSTINT('rowid') ? GETPOSTINT('rowid') : GETPOSTINT('id');
$rowid = $id;
$ref = GETPOST('ref', 'alphanohtml');
$typeid = GETPOSTINT('typeid');
$cancel = GETPOST('cancel');
$cancel = GETPOST('cancel', 'alpha');
// Load variable for pagination
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
@@ -509,11 +508,11 @@ print '<table class="border centpercent tableforfield">';
// Login
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
print '<tr><td class="titlefield">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'</td></tr>';
}
// Type
print '<tr><td class="titlefield">'.$langs->trans("Type").'</td>';
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td>';
print '<td class="valeur">'.$adht->getNomUrl(1)."</td></tr>\n";
// Morphy
@@ -589,7 +588,7 @@ if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
}
// Birth Date
print '<tr><td class="titlefield">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
print '<tr><td class="titlefieldmiddle">'.$langs->trans("DateOfBirth").'</td><td class="valeur">'.dol_print_date($object->birth, 'day').'</td></tr>';
// Default language
if (getDolGlobalInt('MAIN_MULTILANGS')) {
@@ -1021,7 +1020,7 @@ if (($action == 'addsubscription' || $action == 'create_thirdparty') && $user->h
if ($adht->subscription) {
// Amount
print '<tr><td class="fieldrequired">'.$langs->trans("Amount").'</td>';
print '<td><input autofocus class="width50" type="text" name="subscription" value="'.(GETPOSTISSET('subscription') ? GETPOST('subscription') : (is_null($adht->amount) ? '' : price($adht->amount, 0, '', 0))).'"> '.$langs->trans("Currency".$conf->currency) .'</td></tr>';
print '<td><input autofocus class="width50" type="text" name="subscription" value="'.(GETPOSTISSET('subscription') ? GETPOST('subscription') : (is_null($adht->amount) ? '' : price($adht->amount, 0, '', 0))).'"> '.$langs->trans("Currency".getDolCurrency()) .'</td></tr>';
// Label
print '<tr><td>'.$langs->trans("Label").'</td>';

View File

@@ -539,43 +539,43 @@ if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.ref']['checked'])) {
print_liste_field_titre($arrayfields['d.ref']['label'], $_SERVER["PHP_SELF"], "c.rowid", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.ref']['label'], $_SERVER["PHP_SELF"], "c.rowid", "", $param, "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.fk_type']['checked'])) {
print_liste_field_titre($arrayfields['d.fk_type']['label'], $_SERVER["PHP_SELF"], "c.fk_type", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.fk_type']['label'], $_SERVER["PHP_SELF"], "c.fk_type", "", $param, "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.lastname']['checked'])) {
print_liste_field_titre($arrayfields['d.lastname']['label'], $_SERVER["PHP_SELF"], "d.lastname", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.lastname']['label'], $_SERVER["PHP_SELF"], "d.lastname", "", $param, "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.firstname']['checked'])) {
print_liste_field_titre($arrayfields['d.firstname']['label'], $_SERVER["PHP_SELF"], "d.firstname", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.firstname']['label'], $_SERVER["PHP_SELF"], "d.firstname", "", $param, "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.login']['checked'])) {
print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", "", $param, "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['c.note']['checked'])) {
print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder);
print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", "", $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.bank']['checked'])) {
print_liste_field_titre($arrayfields['d.bank']['label'], $_SERVER["PHP_SELF"], "b.fk_account", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre($arrayfields['d.bank']['label'], $_SERVER["PHP_SELF"], "b.fk_account", "", $param, "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['c.dateadh']['checked'])) {
print_liste_field_titre($arrayfields['c.dateadh']['label'], $_SERVER["PHP_SELF"], "c.dateadh", $param, "", '', $sortfield, $sortorder, 'center nowraponall ');
print_liste_field_titre($arrayfields['c.dateadh']['label'], $_SERVER["PHP_SELF"], "c.dateadh", "", $param, '', $sortfield, $sortorder, 'center nowraponall ');
$totalarray['nbfield']++;
}
if (!empty($arrayfields['c.datef']['checked'])) {
print_liste_field_titre($arrayfields['c.datef']['label'], $_SERVER["PHP_SELF"], "c.datef", $param, "", '', $sortfield, $sortorder, 'center nowraponall ');
print_liste_field_titre($arrayfields['c.datef']['label'], $_SERVER["PHP_SELF"], "c.datef", "", $param, '', $sortfield, $sortorder, 'center nowraponall ');
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.amount']['checked'])) {
print_liste_field_titre($arrayfields['d.amount']['label'], $_SERVER["PHP_SELF"], "c.subscription", $param, "", '', $sortfield, $sortorder, 'right ');
print_liste_field_titre($arrayfields['d.amount']['label'], $_SERVER["PHP_SELF"], "c.subscription", "", $param, '', $sortfield, $sortorder, 'right ');
$totalarray['nbfield']++;
}

View File

@@ -485,7 +485,13 @@ if (!$rowid && $action != 'create' && $action != 'edit') {
print '<td class="center">'.yn($objp->subscription).'</td>';
}
if (!empty($arrayfields['t.amount']['checked'])) {
print '<td class="center"><span class="amount">'.(is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount)).'</span></td>';
print '<td class="center">';
$amount = (is_null($objp->amount) || $objp->amount === '' ? '' : price($objp->amount));
print '<span class="amount">'.$amount.'</span>';
if ($amount && $amount < (float) getDolGlobalInt("MEMBER_MIN_AMOUNT")) {
print img_warning('Amount lower than minimum of '.price(getDolGlobalInt("MEMBER_MIN_AMOUNT")).' defined in setup');
}
print '</td>';
}
if (!empty($arrayfields['t.caneditamount']['checked'])) {
print '<td class="center">'.yn($objp->caneditamount).'</td>';
@@ -645,7 +651,11 @@ if ($rowid > 0) {
// Amount
print '<tr><td class="titlefield">'.$langs->trans("Amount").'</td><td>';
print((is_null($object->amount) || $object->amount === '') ? '' : '<span class="amount">'.price($object->amount).'</span>');
$amount = ((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount));
print '<span class="amount">'.$amount.'</span>';
if ($amount && $amount < (float) getDolGlobalInt("MEMBER_MIN_AMOUNT")) {
print ' '.img_warning('Amount lower than minimum of '.price(getDolGlobalInt("MEMBER_MIN_AMOUNT")).' defined in setup');
}
print '</tr>';
print '<tr><td>'.$form->textwithpicto($langs->trans("CanEditAmountShort"), $langs->transnoentities("CanEditAmount")).'</td><td>';
@@ -915,17 +925,17 @@ if ($rowid > 0) {
print '<tr class="liste_titre">';
if ($conf->main_checkbox_left_column) {
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", "", $param, 'width="60" align="center"', $sortfield, $sortorder);
}
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "d.ref", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre("NameSlashCompany", $_SERVER["PHP_SELF"], "d.lastname", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre("Login", $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre("MemberNature", $_SERVER["PHP_SELF"], "d.morphy", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "d.email", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "d.statut,d.datefin", $param, "", "", $sortfield, $sortorder);
print_liste_field_titre("EndSubscription", $_SERVER["PHP_SELF"], "d.datefin", $param, "", 'align="center"', $sortfield, $sortorder);
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "d.ref", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("NameSlashCompany", $_SERVER["PHP_SELF"], "d.lastname", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Login", $_SERVER["PHP_SELF"], "d.login", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("MemberNature", $_SERVER["PHP_SELF"], "d.morphy", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("EMail", $_SERVER["PHP_SELF"], "d.email", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "d.statut,d.datefin", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("EndSubscription", $_SERVER["PHP_SELF"], "d.datefin", "", $param, 'align="center"', $sortfield, $sortorder);
if (!$conf->main_checkbox_left_column) {
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", "", $param, 'width="60" align="center"', $sortfield, $sortorder);
}
print "</tr>\n";
@@ -944,7 +954,6 @@ if ($rowid > 0) {
$adh->firstname = $objp->firstname;
$adh->datefin = $datefin;
$adh->need_subscription = $objp->subscription;
$adh->statut = $objp->status;
$adh->status = $objp->status;
$adh->email = $objp->email;
$adh->photo = $objp->photo;
@@ -1089,8 +1098,9 @@ if ($rowid > 0) {
print '</td></tr>';
print '<tr><td>'.$langs->trans("Amount").'</td><td>';
$amount = ((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount));
print '<input name="amount" size="5" value="';
print((is_null($object->amount) || $object->amount === '') ? '' : price($object->amount));
print $amount;
print '">';
print '</td></tr>';

View File

@@ -152,6 +152,53 @@ $linkback = '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/admin/modules.php', ['restore
print load_fiche_titre($langs->trans("BarcodeSetup"), $linkback, 'title_setup');
print '<br>';
/*
* Usage
*/
print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
print '<input type="hidden" name="token" value="'.newToken().'">';
print "<input type=\"hidden\" name=\"action\" value=\"update\">";
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Feature").'</td>';
print '<td width="60" class="center"></td>';
print '<td>&nbsp;</td>';
print '</tr>';
// Module products
if (isModEnabled('product')) {
print '<tr class="oddeven">';
print '<td>'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("UseBarCodeForProducts").'</td>';
print '<td width="60" class="right">';
print ajax_constantonoff('BARCODE_USE_ON_PRODUCT', array(), null, 0, 0, 1);
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
// Module thirdparty
if (isModEnabled('societe')) {
print '<tr class="oddeven">';
print '<td>'.img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans("UseBarCodeForThirdParties").'</td>';
print '<td width="60" class="right">';
print ajax_constantonoff('BARCODE_USE_ON_THIRDPARTY', array(), null, 0, 0, 1);
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
print "</table>\n";
print '</div>';
print '<br>';
// Detect bar codes modules
$barcodelist = array();
@@ -175,6 +222,7 @@ foreach ($dirbarcode as $reldir) {
while (($file = readdir($handle)) !== false) {
if (substr($file, 0, 1) != '.' && substr($file, 0, 3) != 'CVS') {
if (is_readable($newdir.$file)) {
$reg = array();
if (preg_match('/(.*)\.modules\.php$/i', $file, $reg)) {
$filebis = $reg[1];
@@ -206,7 +254,7 @@ foreach ($dirbarcode as $reldir) {
// Select barcode numbering module
if (isModEnabled('product')) {
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') && isModEnabled('product')) {
print load_fiche_titre($langs->trans("BarCodeNumberManager")." (".$langs->trans("Product").")", '', 'product');
print '<div class="div-table-responsive-no-min">';
@@ -273,7 +321,7 @@ if (isModEnabled('product')) {
}
// Select barcode numbering module
if (isModEnabled('societe')) {
if (getDolGlobalString('BARCODE_USE_ON_THIRDPARTY') && isModEnabled('societe')) {
print load_fiche_titre($langs->trans("BarCodeNumberManager")." (".$langs->trans("ThirdParty").")", '', 'company');
print '<div class="div-table-responsive-no-min">';
@@ -343,172 +391,175 @@ if (isModEnabled('societe')) {
/*
* CHOOSE ENCODING
*/
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') || getDolGlobalString('BARCODE_USE_ON_THIRDPARTY')) {
print load_fiche_titre($langs->trans("BarcodeEncodeModule"), '', '');
print load_fiche_titre($langs->trans("BarcodeEncodeModule"), '', '');
if (empty($conf->use_javascript_ajax)) {
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" id="form_engine">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="updateengine">';
}
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td width="200" class="center">'.$langs->trans("Example").'</td>';
print '<td class="center" width="60">'.$langs->trans("CodeBarGenerator").'</td>';
print "</tr>\n";
$sql = "SELECT rowid, code as encoding, libelle as label, coder, example";
$sql .= " FROM ".MAIN_DB_PREFIX."c_barcode_type";
$sql .= " WHERE entity = ".$conf->entity;
$sql .= " ORDER BY code";
dol_syslog("admin/barcode.php", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
print '<td width="100">';
print dol_escape_htmltag($obj->label);
print "</td><td>\n";
print $langs->trans('BarcodeDesc'.$obj->encoding);
//print "L'EAN se compose de 8 characters, 7 chiffres plus une cle de verification.<br>";
//print "L'utilisation des symbologies EAN8 impose la souscription et l'abonnement aupres d'organismes comme GENCOD.<br>";
//print "Codes numeriques utilises exclusivement a l'identification des produits susceptibles d'etre vendus au grand public.";
print '</td>';
// Show example
print '<td class="center">';
if ($obj->coder && $obj->coder != -1) {
$result = 0;
foreach ($dirbarcode as $reldir) {
$dir = dol_buildpath($reldir, 0);
$newdir = dol_osencode($dir);
// Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php)
if (!is_dir($newdir)) {
continue;
}
$result = @include_once $newdir.$obj->coder.'.modules.php';
if ($result) {
break;
}
}
if ($result) {
$classname = "mod".ucfirst($obj->coder);
if (class_exists($classname)) {
$module = new $classname($db);
'@phan-var-force ModeleBarCode $module';
if ($module->encodingIsSupported($obj->encoding)) {
// Build barcode on disk (not used, this is done to make debug easier)
$result = $module->writeBarCode($obj->example, $obj->encoding, 'Y');
// Generate on the fly and output barcode with generator
$url = DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&amp;generator='.urlencode($obj->coder).'&amp;code='.urlencode($obj->example).'&amp;encoding='.urlencode($obj->encoding);
//print $url;
print '<img src="'.$url.'" title="'.$obj->example.'" border="0">';
} else {
print $langs->trans("FormatNotSupportedByGenerator");
}
} else {
print 'ErrorClassNotFoundInModule '.$classname.' '.$obj->coder;
}
}
} else {
print '<span class="opacitymedium">'.$langs->trans("ChooseABarCode").'</span>';
}
print '</td>';
print '<td class="center">';
print $formbarcode->setBarcodeEncoder($obj->coder, $barcodelist, $obj->rowid, 'form'.$i);
print "</td></tr>\n";
$i++;
if (empty($conf->use_javascript_ajax)) {
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" id="form_engine">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="updateengine">';
}
}
print "</table>\n";
print '</div>';
if (empty($conf->use_javascript_ajax)) {
print $form->buttonsSaveCancel("Save", '');
}
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td width="200" class="center">'.$langs->trans("Example").'</td>';
print '<td class="center" width="60">'.$langs->trans("CodeBarGenerator").'</td>';
print "</tr>\n";
print "<br>";
$sql = "SELECT rowid, code as encoding, libelle as label, coder, example";
$sql .= " FROM ".MAIN_DB_PREFIX."c_barcode_type";
$sql .= " WHERE entity = ".$conf->entity;
$sql .= " ORDER BY code";
dol_syslog("admin/barcode.php", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
print '<td width="100">';
print dol_escape_htmltag($obj->label);
print "</td><td>\n";
print $langs->trans('BarcodeDesc'.$obj->encoding);
//print "L'EAN se compose de 8 characters, 7 chiffres plus une cle de verification.<br>";
//print "L'utilisation des symbologies EAN8 impose la souscription et l'abonnement aupres d'organismes comme GENCOD.<br>";
//print "Codes numeriques utilises exclusivement a l'identification des produits susceptibles d'etre vendus au grand public.";
print '</td>';
// Show example
print '<td class="center">';
if ($obj->coder && $obj->coder != -1) {
$result = 0;
foreach ($dirbarcode as $reldir) {
$dir = dol_buildpath($reldir, 0);
$newdir = dol_osencode($dir);
// Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php)
if (!is_dir($newdir)) {
continue;
}
$result = @include_once $newdir.$obj->coder.'.modules.php';
if ($result) {
break;
}
}
if ($result) {
$classname = "mod".ucfirst($obj->coder);
if (class_exists($classname)) {
$module = new $classname($db);
'@phan-var-force ModeleBarCode $module';
if ($module->encodingIsSupported($obj->encoding)) {
// Build barcode on disk (not used, this is done to make debug easier)
$result = $module->writeBarCode($obj->example, $obj->encoding, 'Y');
// Generate on the fly and output barcode with generator
$url = DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&amp;generator='.urlencode($obj->coder).'&amp;code='.urlencode($obj->example).'&amp;encoding='.urlencode($obj->encoding);
//print $url;
print '<img src="'.$url.'" title="'.$obj->example.'" border="0">';
} else {
print $langs->trans("FormatNotSupportedByGenerator");
}
} else {
print 'ErrorClassNotFoundInModule '.$classname.' '.$obj->coder;
}
}
} else {
print '<span class="opacitymedium">'.$langs->trans("ChooseABarCode").'</span>';
}
print '</td>';
print '<td class="center">';
print $formbarcode->setBarcodeEncoder($obj->coder, $barcodelist, $obj->rowid, 'form'.$i);
print "</td></tr>\n";
$i++;
}
}
print "</table>\n";
print '</div>';
if (empty($conf->use_javascript_ajax)) {
print $form->buttonsSaveCancel("Save", '');
}
print "<br>";
}
/*
* Other options
*/
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') || getDolGlobalString('BARCODE_USE_ON_THIRDPARTY')) {
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
print '<input type="hidden" name="token" value="'.newToken().'">';
print "<input type=\"hidden\" name=\"action\" value=\"update\">";
print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
print '<input type="hidden" name="token" value="'.newToken().'">';
print "<input type=\"hidden\" name=\"action\" value=\"update\">";
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameter").'</td>';
print '<td width="60" class="center"></td>';
print '<td>&nbsp;</td>';
print '</tr>';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameter").'</td>';
print '<td width="60" class="center"></td>';
print '<td>&nbsp;</td>';
print '</tr>';
// Chemin du binaire genbarcode sous linux
if (!isset($_SERVER['WINDIR'])) {
print '<tr class="oddeven">';
print '<td>'.$langs->trans("GenbarcodeLocation").'</td>';
print '<td width="60" class="center">';
print '<input type="text" size="40" name="GENBARCODE_LOCATION" value="'.getDolGlobalString('GENBARCODE_LOCATION').'">';
if (getDolGlobalString('GENBARCODE_LOCATION') && !@file_exists($conf->global->GENBARCODE_LOCATION)) {
$langs->load("errors");
print '<br><span class="error">'.$langs->trans("ErrorFileNotFound", getDolGlobalString('GENBARCODE_LOCATION')).'</span>';
// Chemin du binaire genbarcode sous linux
if (!isset($_SERVER['WINDIR'])) {
print '<tr class="oddeven">';
print '<td>'.$langs->trans("GenbarcodeLocation").'</td>';
print '<td width="60" class="center">';
print '<input type="text" size="40" name="GENBARCODE_LOCATION" value="'.getDolGlobalString('GENBARCODE_LOCATION').'">';
if (getDolGlobalString('GENBARCODE_LOCATION') && !@file_exists($conf->global->GENBARCODE_LOCATION)) {
$langs->load("errors");
print '<br><span class="error">'.$langs->trans("ErrorFileNotFound", getDolGlobalString('GENBARCODE_LOCATION')).'</span>';
}
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
// Module products
if (getDolGlobalString('BARCODE_USE_ON_PRODUCT') && isModEnabled('product')) {
print '<tr class="oddeven">';
print '<td>'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeProducts").'</td>';
print '<td width="60" class="right">';
print $formbarcode->selectBarcodeType(getDolGlobalInt('PRODUIT_DEFAULT_BARCODE_TYPE'), "PRODUIT_DEFAULT_BARCODE_TYPE", 1);
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
// Module thirdparty
if (getDolGlobalString('BARCODE_USE_ON_THIRDPARTY') && isModEnabled('societe')) {
print '<tr class="oddeven">';
print '<td>'.img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeThirdParties").'</td>';
print '<td width="60" class="right">';
print $formbarcode->selectBarcodeType(getDolGlobalInt('GENBARCODE_BARCODETYPE_THIRDPARTY'), "GENBARCODE_BARCODETYPE_THIRDPARTY", 1);
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
print "</table>\n";
print '</div>';
print '<div class="tabsAction">';
print '<input type="submit" class="button" name="submit_GENBARCODE_BARCODETYPE_THIRDPARTY" value="'.$langs->trans("Modify").'">';
print "</div>";
print '</form>';
print '<br>';
}
// Module products
if (isModEnabled('product')) {
print '<tr class="oddeven">';
print '<td>'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeProducts").'</td>';
print '<td width="60" class="right">';
print $formbarcode->selectBarcodeType(getDolGlobalInt('PRODUIT_DEFAULT_BARCODE_TYPE'), "PRODUIT_DEFAULT_BARCODE_TYPE", 1);
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
// Module thirdparty
if (isModEnabled('societe')) {
print '<tr class="oddeven">';
print '<td>'.img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans("SetDefaultBarcodeTypeThirdParties").'</td>';
print '<td width="60" class="right">';
print $formbarcode->selectBarcodeType(getDolGlobalInt('GENBARCODE_BARCODETYPE_THIRDPARTY'), "GENBARCODE_BARCODETYPE_THIRDPARTY", 1);
print '</td>';
print '<td>&nbsp;</td>';
print '</tr>';
}
print "</table>\n";
print '</div>';
print '<div class="tabsAction">';
print '<input type="submit" class="button" name="submit_GENBARCODE_BARCODETYPE_THIRDPARTY" value="'.$langs->trans("Modify").'">';
print "</div>";
print '</form>';
print '<br>';
// End of page
llxFooter();

View File

@@ -470,7 +470,7 @@ print '<input name="name" id="name" maxlength="'.$mysoc->fields['nom']['length']
// Main currency
print '<tr class="oddeven"><td class="fieldrequired"><label for="currency">'.$langs->trans("CompanyCurrency").'</label></td><td>';
print img_picto('', 'multicurrency', 'class="pictofixedwidth"');
print $form->selectCurrency($conf->currency, "currency", 2);
print $form->selectCurrency(getDolCurrency(), "currency", 2);
print '</td></tr>'."\n";
// Country

View File

@@ -40,6 +40,7 @@
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
@@ -2831,6 +2832,7 @@ function dictFieldList($fieldlist, $obj = null, $tabname = '', $context = '')
$formadmin = new FormAdmin($db);
$formcompany = new FormCompany($db);
$formaccounting = new FormAccounting($db);
$formother = new FormOther($db);
$withentity = '';
@@ -3035,6 +3037,10 @@ function dictFieldList($fieldlist, $obj = null, $tabname = '', $context = '')
print '<td>';
print $form->selectTypeDuration('', (empty($obj->type_duration) ? '' : $obj->type_duration), ['s', 'i', 'h']);
print '</td>';
} elseif ($value == 'color') {
print '<td>';
print $formother->selectColor((empty($obj->{$value}) ? '' : $obj->{$value}), 'color');
print '</td>';
} else {
$fieldValue = isset($obj->{$value}) ? $obj->{$value} : '';
$classtd = '';

View File

@@ -67,7 +67,7 @@ $id = GETPOSTINT('id');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'emailcollectorcard'; // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha');

View File

@@ -44,7 +44,7 @@ $langs->loadLangs(array("admin", "eventorganization", "categories"));
// Parameters
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$value = GETPOST('value', 'alpha');

View File

@@ -46,7 +46,7 @@ $langs->loadLangs(array("admin", "eventorganization", "categories"));
// Parameters
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$value = GETPOST('value', 'alpha');

View File

@@ -341,7 +341,7 @@ foreach ($rules as $rule) {
if ($action == 'edit' && $object->id == $rule->id) {
echo '<input type="text" value="' . price2num($object->amount) . '" name="amount" class="amount width50 right" />';
} else {
echo price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency);
echo price($rule->amount, 0, $langs, 1, -1, -1, getDolCurrency());
}
echo '</td>';

View File

@@ -83,12 +83,23 @@ if (getDolGlobalString('MAIN_MOTD_SETUPPAGE')) {
print '<span class="opacitymedium hideonsmartphone">';
print $langs->trans("SetupDescription1").'<br>';
//print $langs->trans("AreaForAdminOnly").' ';
print '<br>';
print $langs->trans("SetupDescription2", $langs->transnoentities("MenuCompanySetup"), $langs->transnoentities("Modules"));
if (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') || !getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY') || getDolGlobalString('MAIN_INFO_SOCIETE_SETUP_TODO_WARNING')) {
$setupcompanynotcomplete = 1;
} else {
$setupcompanynotcomplete = 0;
}
if ($setupcompanynotcomplete) {
print '<br>';
print $langs->trans("SetupDescription2", $langs->transnoentities("MenuCompanySetup"), $langs->transnoentities("Modules"));
}
print "<br><br>";
print '</span>';
// Show info depending on country if defined
$constkey = 'MAIN_INFO_SETUP_FOR_COUNTRY_'.$mysoc->country_code;
//$conf->global->$constkey = 'rrr';
@@ -104,12 +115,6 @@ print '<br>';
// Show info setup company
if (!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') || !getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY') || getDolGlobalString('MAIN_INFO_SOCIETE_SETUP_TODO_WARNING')) {
$setupcompanynotcomplete = 1;
} else {
$setupcompanynotcomplete = 0;
}
print '<section class="setupsection setupcompany cursorpointer">';
print img_picto('', 'company', 'class="paddingright valignmiddle double"');

View File

@@ -42,12 +42,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
$langs->loadLangs(array('companies', 'products', 'admin'));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$currencycode = GETPOST('currencycode', 'alpha');
if (isModEnabled('multicompany') && getDolGlobalString('MULTICURRENCY_USE_LIMIT_BY_CURRENCY')) {
// When MULTICURRENCY_USE_LIMIT_BY_CURRENCY is on, we use always a defined currency code instead of '' even for default.
$currencycode = (!empty($currencycode) ? $currencycode : $conf->currency);
$currencycode = (!empty($currencycode) ? $currencycode : getDolCurrency());
}
$mainmaxdecimalsunit = 'MAIN_MAX_DECIMALS_UNIT'.(!empty($currencycode) ? '_'.$currencycode : '');
@@ -137,14 +137,14 @@ llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-admin page-limits');
print load_fiche_titre($title, '', 'title_setup');
$aCurrencies = array($conf->currency); // Default currency always first position
$aCurrencies = array(getDolCurrency()); // Default currency always first position
if (isModEnabled('multicompany') && getDolGlobalString('MULTICURRENCY_USE_LIMIT_BY_CURRENCY')) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/multicurrency.lib.php';
$sql = "SELECT rowid, code FROM " . MAIN_DB_PREFIX . "multicurrency";
$sql .= " WHERE entity = " . ((int) $conf->entity);
$sql .= " AND code <> '" . $db->escape($conf->currency) . "'"; // Default currency always first position
$sql .= " AND code <> '" . $db->escape(getDolCurrency()) . "'"; // Default currency always first position
$resql = $db->query($sql);
if ($resql) {
while ($obj = $db->fetch_object($resql)) {

View File

@@ -45,7 +45,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
$langs->loadLangs(array("companies", "products", "admin", "mails", "other", "errors"));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$trackid = GETPOST('trackid');

View File

@@ -42,7 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$usersignature = $user->signature;
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.

View File

@@ -41,7 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$langs->loadLangs(array("companies", "products", "admin", "mails", "other", "errors"));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$trackid = GETPOST('trackid');

View File

@@ -42,7 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$usersignature = $user->signature;
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.

View File

@@ -38,6 +38,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
@@ -47,14 +54,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/cemailtemplate.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langsArray = array("errors", "admin", "mails", "languages");
@@ -115,6 +114,26 @@ if (empty($sortorder)) {
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
$hookmanager->initHooks(array('emailtemplates'));
$object = new CEmailTemplate($db);
// Definition of array of fields for columns from ->fields
$tableprefix = 't';
$arrayfields = array();
foreach ($object->fields as $key => $val) {
// If $val['visible']==0, then we never show the field
if (!empty($val['visible'])) {
$visible = (int) dol_eval((string) $val['visible'], 1);
$arrayfields[$tableprefix.'.'.$key] = array(
'label' => $val['label'],
'checked' => (($visible < 0) ? '0' : '1'),
'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
'position' => $val['position'],
'help' => isset($val['help']) ? $val['help'] : ''
);
}
}
// Old way to define field.
// Name of SQL tables of dictionaries
$tabname = array();
@@ -123,7 +142,7 @@ $tabname[25] = MAIN_DB_PREFIX."c_email_templates";
// Nom des champs en resultat de select pour affichage du dictionnaire
// Names of fields in select results for dictionary display (AI translated)
$tabfield = array();
$tabfield[25] = "label,lang,type_template,fk_user,private,position,module,topic,joinfiles,defaultfortype,content";
$tabfield[25] = "label,lang,type_template,fk_user,position,module,topic,joinfiles,defaultfortype,content";
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$tabfield[25] .= ',content_lines';
}
@@ -145,10 +164,6 @@ if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
}
$tabfieldinsert[25] .= ',entity'; // Must be at end because not into other arrays
// Condition to show dictionary in setup page
$tabcond = array();
$tabcond[25] = true;
// List of help for fields
// Set MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES to allow edit of template for lines
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
@@ -257,7 +272,7 @@ if (isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')) {
if (isModEnabled('agenda')) {
$elementList['actioncomm_send'] = img_picto('', 'action', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendEventPush'));
}
if (isModEnabled('eventorganization') && $user->hasRight('eventorganization', 'read')) {
if (isModEnabled('eventorganization') && $user->hasRight('project', 'read')) {
$elementList['conferenceorbooth'] = img_picto('', 'action', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendEventOrganization'));
}
if (isModEnabled('partnership') && $user->hasRight('partnership', 'read')) {
@@ -638,7 +653,8 @@ if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu
$morejs = array();
$morecss = array();
$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, email_from,joinfiles, defaultfortype, content_lines, content, enabled, active, tms, datec";
$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, email_from, joinfiles, defaultfortype,";
$sql .= " content_lines, content, enabled, active, tms, datec";
$sql .= " FROM ".MAIN_DB_PREFIX."c_email_templates";
$sql .= " WHERE entity IN (".getEntity('email_template').")";
if (!$user->admin) {
@@ -1025,9 +1041,14 @@ foreach ($fieldlist as $field => $value) {
}*/
// Status
print '<td></td>';
// Have to expand the id="Title line with search boxes" with 2 extra fields because the line below id="Title of lines" are 2 fields longer
print '<td></td>'; // tms / Modif. date
print '<td></td>'; // datec / Date creation
if (!empty($arrayfields['t.tms']['checked'])) {
print '<td></td>'; // tms / Modif. date
}
if (!empty($arrayfields['t.datec']['checked'])) {
print '<td></td>'; // datec / Date creation
}
// Action column
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print '<td class="liste_titre center" width="64">';
@@ -1104,6 +1125,12 @@ foreach ($fieldlist as $field => $value) {
$valuetoshow = $langs->trans("ContentForLines");
$showfield = 0;
}
if ($value == 'tms' && empty($arrayfields['t'.$value]['checked'])) {
$showfield = 0;
}
if ($value == 'datec' && empty($arrayfields['t.'.$value]['checked'])) {
$showfield = 0;
}
// Show fields
if ($showfield) {
@@ -1153,16 +1180,19 @@ if ($num) {
$colspan = 0;
print '<tr><td colspan="12">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="rowid" value="'.$rowid.'">';
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
if ($action == 'edit') {
print '<input type="submit" class="button buttongen button-save" name="actionmodify" value="'.$langs->trans("Save").'">';
}
print '<input type="submit" class="button buttongen button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '</td></tr>';
// Action column
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print '<td class="center">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="rowid" value="'.$rowid.'">';
if ($action == 'edit') {
print '<input type="submit" class="button buttongen button-save" name="actionmodify" value="'.$langs->trans("Modify").'">';
}
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
print '<input type="submit" class="button buttongen button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '</td>';
$colspan++;
}
@@ -1348,6 +1378,11 @@ if ($num) {
$fuser = new User($db);
$fuser->fetch($valuetoshow);
$valuetoshow = $fuser->getNomUrl(-1);
if ($obj->private) {
$valuetoshow = img_picto($langs->transnoentitiesnoconv("Private"), 'lock', 'class="pictofixedwidth"').$valuetoshow;
}
$class .= ' tdoverflowmax100';
}
}
@@ -1375,6 +1410,13 @@ if ($num) {
$class .= ' '.$css;
}
if ($value == 'tms' && empty($arrayfields['t'.$value]['checked'])) {
$showfield = 0;
}
if ($value == 'datec' && empty($arrayfields['t.'.$value]['checked'])) {
$showfield = 0;
}
// Show value for field
if ($showfield) {
print '<!-- '.$fieldlist[$field].' -->';

View File

@@ -42,7 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$usersignature = $user->signature;
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.

View File

@@ -61,22 +61,13 @@ require_once DOL_DOCUMENT_ROOT.'/admin/remotestore/class/externalModules.class.p
// Load translation files required by the page
$langs->loadLangs(array("errors", "admin", "modulebuilder"));
// if we set another view list mode, we keep it (till we change one more time)
if (GETPOSTISSET('mode')) {
$mode = GETPOST('mode', 'alpha');
if ($mode == 'common' || $mode == 'commonkanban') {
dolibarr_set_const($db, "MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT", $mode, 'chaine', 0, '', $conf->entity);
}
} else {
$mode = getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT', 'commonkanban');
}
$action = GETPOST('action', 'aZ09');
$page_y = GETPOSTINT('page_y');
$optioncss = GETPOST('optioncss', 'aZ09');
$sortfield = GETPOST('sortfield', 'aZ09');
$sortorder = GETPOST('sortorder', 'aZ09');
$mode = GETPOST('mode', 'alpha');
$value = GETPOST('value', 'alpha');
$search_keyword = GETPOST('search_keyword', 'alpha');
$search_status = GETPOST('search_status', 'alpha');
@@ -168,6 +159,7 @@ if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
$debug = false;
$remotestore = new ExternalModules($debug);
if ($mode == 'marketplace') {
// Make remote calls
if (GETPOSTINT('dol_resetcache')) {
@@ -193,6 +185,16 @@ if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
// if we set another view list mode, we keep it (till we change one more time)
if (GETPOSTISSET('mode')) {
$mode = GETPOST('mode', 'alpha');
if ($mode == 'common' && !getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT')) {
dolibarr_set_const($db, "MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT", $mode, 'chaine', 0, '', $conf->entity);
}
} else {
$mode = getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT', 'commonkanban');
}
if (GETPOST('buttonreset', 'alpha')) {
$search_keyword = '';
$search_status = '';
@@ -512,7 +514,7 @@ $filename = array();
$modules = array();
$orders = array();
$categ = array();
$publisherlogoarray = array();
//$publisherlogoarray = array();
$i = 0; // is a sequencer of modules found
$j = 0; // j is module number. Automatically affected if module number not defined.
@@ -617,8 +619,7 @@ foreach ($modulesdir as $dir) {
}
$familyposition = (empty($familyinfo[$familykey]['position']) ? '0' : $familyinfo[$familykey]['position']);
$listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other');
if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) {
if ($external && !in_array($familykey, array_keys($familyinfo))) {
// If module is extern and into a custom group (not into an official predefined one), it must appear at end (custom groups should not be before official groups).
if (is_numeric($familyposition)) {
$familyposition = sprintf("%03d", (int) $familyposition + 100);
@@ -723,9 +724,6 @@ if ($mode == 'common' || $mode == 'commonkanban') {
$deschelp .= '<br>';
}
}
//if ($mode == 'marketplace') {
// $deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesMarketPlaceDesc")."<br></div><br>\n";
//}
if ($mode == 'deploy') {
$deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesDeployDesc", $langs->transnoentitiesnoconv("AvailableModules"))."<br></div><br>\n";
}
@@ -800,7 +798,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
$moreforfilter .= '<input type="submit" name="buttonsubmit" class="button small nomarginleft" value="'.dolPrintHTMLForAttribute($langs->trans("Refresh")).'">';
if ($search_keyword || ($search_nature && $search_nature != '-1') || ($search_version && $search_version != '-1') || ($search_status && $search_status != '-1')) {
$moreforfilter .= ' ';
$moreforfilter .= '<input type="submit" name="buttonreset" class="buttonreset noborderbottom nomargintop nomarginbottom" value="'.dolPrintHTMLForAttribute($langs->trans("Reset")).'">';
$moreforfilter .= '<input type="submit" name="buttonreset" class="buttonreset noborderall nomargintop nomarginbottom" value="'.dolPrintHTMLForAttribute($langs->trans("Reset")).'">';
}
$moreforfilter .= '</div>';
$moreforfilter .= '</div>';
@@ -1420,7 +1418,7 @@ if ($mode == 'marketplace') {
<div id="listing-content" class="div-table-responsive" <?php if (empty($categories_tree)) { ?>style="width:100%;"<?php } ?>>
<table summary="list_of_modules" id="list_of_modules" class="productlist centpercent">
<tbody id="listOfModules">
<?php //echo $remotestore->get_products($nbmaxtoshow); ?>
<!-- $product_list is $remotestore->getProducts($options) done previously -->
<?php print $products_list; ?>
</tbody>
</table>

View File

@@ -289,7 +289,7 @@ print '<table class="noborder centpercent nomarginbottom">';
print '<tr class="liste_titre">';
print '<td>'.$form->textwithpicto($langs->trans("CurrenciesUsed"), $langs->transnoentitiesnoconv("CurrenciesUsed_help_to_add")).'</td>'."\n";
print '<td class="right">'.$langs->trans("Rate").' / '.$langs->getCurrencySymbol($conf->currency).'</td>'."\n";
print '<td class="right">'.$langs->trans("Rate").' / '.$langs->getCurrencySymbol(getDolCurrency()).'</td>'."\n";
print '</tr>';
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
@@ -308,10 +308,10 @@ print '</form>';
// Main currency
print '<tr class="oddeven">';
print '<td>'.$conf->currency;
print ' ('.$langs->getCurrencySymbol($conf->currency).')';
print '<td>'.getDolCurrency();
print ' ('.$langs->getCurrencySymbol(getDolCurrency()).')';
print $form->textwithpicto(' ', $langs->trans("BaseCurrency"));
if (!empty($TAvailableCurrency[$conf->currency]) && empty($TAvailableCurrency[$conf->currency]['active'])) {
if (!empty($TAvailableCurrency[getDolCurrency()]) && empty($TAvailableCurrency[getDolCurrency()]['active'])) {
print img_warning('Warning: This code has been disabled into Home - Setup - Dictionaries - Currencies');
}
print '</td>';
@@ -319,7 +319,7 @@ print '<td class="right">1</td>';
print '</tr>';
foreach ($TCurrency as &$currency) {
if ($currency->code == $conf->currency) {
if ($currency->code == getDolCurrency()) {
continue;
}
@@ -334,7 +334,7 @@ foreach ($TCurrency as &$currency) {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update_currency">';
print '<input type="hidden" name="fk_multicurrency" value="'.$currency->id.'">';
print '1 '.$conf->currency.' = ';
print '1 '.getDolCurrency().' = ';
print '<input type="text" name="rate" class="width125 right" value="'.($currency->rate->rate ? $currency->rate->rate : '').'">&nbsp;'.$currency->code.'&nbsp;';
print '<input type="submit" name="updatecurrency" class="button button-edit smallpaddingimp" value="'.$langs->trans("Modify").'">&nbsp;';
print '<input type="submit" name="deletecurrency" class="button smallpaddingimp" value="'.$langs->trans("Delete").'">';

View File

@@ -613,7 +613,7 @@ if ($conf->use_javascript_ajax) {
print '</td></tr>';
// Switch in Bold
/* Fight against optionflation: We don't need this for common usage. Must remain as advanced option.
print '<tr class="oddeven"><td>'.$langs->trans("BoldLabelOnPDF").'</td><td>';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('PDF_BOLD_PRODUCT_LABEL');
@@ -621,9 +621,10 @@ if ($conf->use_javascript_ajax) {
print $form->selectyesno('PDF_BOLD_PRODUCT_LABEL', getDolGlobalInt('PDF_BOLD_PRODUCT_LABEL'), 1);
}
print '</td></tr>';
*/
// Switch in Bold
/* Fight against optionflation: We don't need this for common usage. Must remain as advanced option.
print '<tr class="oddeven"><td>'.$langs->trans("BoldRefAndPeriodOnPDF").'</td><td>';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('PDF_BOLD_PRODUCT_REF_AND_PERIOD');
@@ -631,6 +632,7 @@ if ($conf->use_javascript_ajax) {
print $form->selectyesno('PDF_BOLD_PRODUCT_REF_AND_PERIOD', getDolGlobalInt('PDF_BOLD_PRODUCT_REF_AND_PERIOD'), 1);
}
print '</td></tr>';
*/
// SHOW_SUBPRODUCT_REF_IN_PDF - Option to show the detail of product ref for kits.

View File

@@ -168,7 +168,7 @@ if ($action == 'update') {
}
// add file to concat
foreach (array('MAIN_INFO_PROPAL_TERMSOFSALE', 'MAIN_INFO_ORDER_TERMSOFSALE', 'MAIN_INFO_INVOICE_TERMSOFSALE') as $varname) {
if ($_FILES[$varname]["name"]) {
if (isset($_FILES[$varname]) && $_FILES[$varname]["name"]) {
if (!preg_match('/(\.pdf)$/i', $_FILES[$varname]["name"])) { // Document can be used on a lot of different places. Only pdf can be supported.
$langs->load("errors");
setEventMessages($langs->trans("ErrorBadFormat"), null, 'errors');

View File

@@ -366,6 +366,22 @@ class ExternalModules
$this->numberTotalOfProducts = 0;
// Special case of category goodies
if ($this->categorie == 87) {
$html = '<div class="shop-container">
<div class="shop-image">
<a href="https://merch.dolibarr.org/" target="_blank">
<img src="https://www.dolistore.com/medias/image/marketplace/img/goodies-shop.jpg" width="50%" alt="DoliStore Merch and Gifts" />
<div class="shop-overlay">
<button target="new" class="shop-button">'.$langs->trans("GoodiesButtonTitle").' <i class="icon-chevron-right"></i></button>
</div>
</a>
</div>
</div>';
return $html;
}
// Fetch the products from Dolistore source
$dolistoreProducts = array();
@@ -638,7 +654,7 @@ class ExternalModules
$this->numberOfProducts = count($this->products);
return $html ;
return $html;
}
/**

View File

@@ -195,17 +195,48 @@ textarea.row4{
h2.appTitle small{
font-weight: normal;
}
/*
tr.NotCompatible{
opacity: 0.5;
opacity: 1;
}
tr.NotCompatible:hover{
opacity: 0.7;
opacity: 0.9;
}
*/
span.details{
font-size: 1em;
margin-left: 10px;
vertical-align: super;
}
.storedesc {
opacity: 0.5;
}
.shop-container {
border-top: none;
overflow: hidden;
text-align: center;
background-color: #fff;
box-shadow: 0 8px 20px rgba(0, 0, 0, .1);
transition: transform .3s;
transform: scale(1);
}
.shop-button {
position: absolute;
top: 20%;
left: 50%;
padding: 10px 20px;
border: none;
border-radius: 8px;
text-transform: uppercase;
font-size: 16px;
color: #fff;
background-color: #ff5f57;
box-shadow: 0 5px 15px rgba(255, 95, 87, .3);
transition: background-color .3s, transform .3s;
transform: translate(-50%, -50%);
cursor: pointer;
}
@media only screen and (min-width: 1150px) {

View File

@@ -45,7 +45,7 @@ if (!$user->admin) {
}
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$forceCSP = getDolGlobalString("MAIN_SECURITY_FORCECSP");
$selectarrayCSPDirectives = GetContentPolicyDirectives();

View File

@@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
$langs->loadLangs(array("companies", "admin", "products", "sms", "other", "errors"));
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
if (!$user->admin) {
accessforbidden();

View File

@@ -63,7 +63,6 @@ $arrayofparameters = array(
);
$error = 0;
$setupnotempty = 0;
/*
@@ -113,6 +112,7 @@ if ($action == 'updateMask') {
$module = new $classname($db);
'@phan-var-force ModelePDFStockTransfer $module';
/** @var ModelePDFStockTransfer $module */
if ($module->write_file($tmpobject, $langs) > 0) {
header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf");
@@ -181,309 +181,248 @@ print load_fiche_titre($langs->trans($page_name), $linkback, 'stock');
$head = stocktransferAdminPrepareHead();
print dol_get_fiche_head($head, 'settings', '', -1, "stocktransfer@stocktransfer");
/*if ($action == 'edit')
{
print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td></td></tr>';
foreach ($arrayofparameters as $key => $val)
{
print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
print $form->textwithpicto($langs->trans($key), $tooltiphelp);
print '</td><td><input name="'.$key.'" class="flat '.(empty($val['css']) ? 'minwidth200' : $val['css']).'" value="'.getDolGlobalString($key).'"></td></tr>';
}
print '</table>';
print '<br><div class="center">';
print '<input class="button" type="submit" value="'.$langs->trans("Save").'">';
print '</div>';
print '</form>';
print '<br>';
} else {
if (!empty($arrayofparameters))
{
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td></td></tr>';
foreach ($arrayofparameters as $key => $val)
{
$setupnotempty++;
print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
print $form->textwithpicto($langs->trans($key), $tooltiphelp);
print '</td><td>'.getDolGlobalString($key).'</td></tr>';
}
print '</table>';
print '<div class="tabsAction">';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
print '</div>';
}
else
{
print '<br>'.$langs->trans("NothingToSetup");
}
}*/
$moduledir = 'stocktransfer';
$myTmpObjects = array();
$myTmpObjects[$moduledir] = array('includerefgeneration' => 1, 'includedocgeneration' => 1, 'class' => 'StockTransfer');
foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
if ($myTmpObjectArray['includerefgeneration']) {
// Orders Numbering model
$setupnotempty++;
// Orders Numbering model
print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', '');
print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', '');
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td class="nowrap">'.$langs->trans("Example").'</td>';
print '<td class="center" width="60">'.$langs->trans("Status").'</td>';
print '<td class="center" width="16">'.$langs->trans("ShortInfo").'</td>';
print '</tr>'."\n";
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td class="nowrap">'.$langs->trans("Example").'</td>';
print '<td class="center" width="60">'.$langs->trans("Status").'</td>';
print '<td class="center" width="16">'.$langs->trans("ShortInfo").'</td>';
print '</tr>'."\n";
clearstatcache();
clearstatcache();
foreach ($dirmodels as $reldir) {
$dir = dol_buildpath($reldir."core/modules/".$moduledir);
foreach ($dirmodels as $reldir) {
$dir = dol_buildpath($reldir."core/modules/".$moduledir);
if (is_dir($dir)) {
$handle = opendir($dir);
if (is_resource($handle)) {
while (($file = readdir($handle)) !== false) {
if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') {
$file = substr($file, 0, dol_strlen($file) - 4);
require_once $dir.'/'.$file.'.php';
$module = new $file($db);
'@phan-var-force ModeleNumRefStockTransfer $module';
// Show modules according to features level
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
continue;
}
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
continue;
}
if ($module->isEnabled()) {
dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
print $module->info($langs);
print '</td>';
// Show example of numbering model
print '<td class="nowrap">';
$tmp = $module->getExample();
if (preg_match('/^Error/', $tmp)) {
print '<div class="error">'.$langs->trans($tmp).'</div>';
} elseif ($tmp == 'NotConfigured') {
print $langs->trans($tmp);
} else {
print $tmp;
}
print '</td>'."\n";
print '<td class="center">';
$constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON';
if (getDolGlobalString($constforvar) == $file) {
print img_picto($langs->trans("Activated"), 'switch_on');
} else {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&object='.strtolower($myTmpObjectKey).'&value='.$file.'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
}
print '</td>';
$nameofclass = $myTmpObjectArray['class'];
$mytmpinstance = new $nameofclass($db);
$mytmpinstance->initAsSpecimen();
// Info
$htmltooltip = '';
$htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
$nextval = $module->getNextValue($mytmpinstance);
if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
$htmltooltip .= ''.$langs->trans("NextValue").': ';
if ($nextval) {
if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') {
$nextval = $langs->trans($nextval);
}
$htmltooltip .= $nextval.'<br>';
} else {
$htmltooltip .= $langs->trans($module->error).'<br>';
}
}
print '<td class="center">';
print $form->textwithpicto('', $htmltooltip, 1, 'info');
print '</td>';
print "</tr>\n";
}
}
}
closedir($handle);
}
}
}
print "</table></div><br>\n";
// Document templates generators
$type = strtolower($myTmpObjectKey);
print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
// Load array def with activated templates
$def = array();
$sql = "SELECT nom";
$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
$sql .= " WHERE type = '".$db->escape($type)."'";
$sql .= " AND entity = ".((int) $conf->entity);
$resql = $db->query($sql);
if ($resql) {
$i = 0;
$num_rows = $db->num_rows($resql);
while ($i < $num_rows) {
$array = $db->fetch_array($resql);
if (is_array($array)) {
array_push($def, $array[0]);
}
$i++;
}
} else {
dol_print_error($db);
}
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">'."\n";
print '<tr class="liste_titre">'."\n";
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
print "</tr>\n";
clearstatcache();
foreach ($dirmodels as $reldir) {
foreach (array('', '/doc') as $valdir) {
$realpath = $reldir."core/modules/".$moduledir.$valdir;
$dir = dol_buildpath($realpath);
if (is_dir($dir)) {
$handle = opendir($dir);
if (is_resource($handle)) {
$filelist = array();
while (($file = readdir($handle)) !== false) {
if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') {
$file = substr($file, 0, dol_strlen($file) - 4);
require_once $dir.'/'.$file.'.php';
$module = new $file($db);
'@phan-var-force ModeleNumRefStockTransfer $module';
// Show modules according to features level
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
continue;
}
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
continue;
}
if ($module->isEnabled()) {
dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
print $module->info($langs);
print '</td>';
// Show example of numbering model
print '<td class="nowrap">';
$tmp = $module->getExample();
if (preg_match('/^Error/', $tmp)) {
print '<div class="error">'.$langs->trans($tmp).'</div>';
} elseif ($tmp == 'NotConfigured') {
print $langs->trans($tmp);
} else {
print $tmp;
}
print '</td>'."\n";
print '<td class="center">';
$constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON';
if (getDolGlobalString($constforvar) == $file) {
print img_picto($langs->trans("Activated"), 'switch_on');
} else {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&object='.strtolower($myTmpObjectKey).'&value='.$file.'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
}
print '</td>';
$nameofclass = $myTmpObjectArray['class'];
$mytmpinstance = new $nameofclass($db);
$mytmpinstance->initAsSpecimen();
// Info
$htmltooltip = '';
$htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
$nextval = $module->getNextValue($mytmpinstance);
if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
$htmltooltip .= ''.$langs->trans("NextValue").': ';
if ($nextval) {
if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') {
$nextval = $langs->trans($nextval);
}
$htmltooltip .= $nextval.'<br>';
} else {
$htmltooltip .= $langs->trans($module->error).'<br>';
}
}
print '<td class="center">';
print $form->textwithpicto('', $htmltooltip, 1, 'info');
print '</td>';
print "</tr>\n";
}
}
$filelist[] = $file;
}
closedir($handle);
}
}
}
print "</table></div><br>\n";
}
arsort($filelist);
if ($myTmpObjectArray['includedocgeneration']) {
// Document templates generators
$setupnotempty++;
$type = strtolower($myTmpObjectKey);
foreach ($filelist as $file) {
if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
if (file_exists($dir.'/'.$file)) {
$name = substr($file, 4, dol_strlen($file) - 16);
$classname = substr($file, 0, dol_strlen($file) - 12);
print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
require_once $dir.'/'.$file;
$module = new $classname($db);
// Load array def with activated templates
$def = array();
$sql = "SELECT nom";
$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
$sql .= " WHERE type = '".$db->escape($type)."'";
$sql .= " AND entity = ".((int) $conf->entity);
$resql = $db->query($sql);
if ($resql) {
$i = 0;
$num_rows = $db->num_rows($resql);
while ($i < $num_rows) {
$array = $db->fetch_array($resql);
if (is_array($array)) {
array_push($def, $array[0]);
}
$i++;
}
} else {
dol_print_error($db);
}
'@phan-var-force ModelePDFStockTransfer $module';
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">'."\n";
print '<tr class="liste_titre">'."\n";
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
print "</tr>\n";
$modulequalified = 1;
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
$modulequalified = 0;
}
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
$modulequalified = 0;
}
clearstatcache();
foreach ($dirmodels as $reldir) {
foreach (array('', '/doc') as $valdir) {
$realpath = $reldir."core/modules/".$moduledir.$valdir;
$dir = dol_buildpath($realpath);
if (is_dir($dir)) {
$handle = opendir($dir);
if (is_resource($handle)) {
$filelist = array();
while (($file = readdir($handle)) !== false) {
$filelist[] = $file;
}
closedir($handle);
arsort($filelist);
foreach ($filelist as $file) {
if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
if (file_exists($dir.'/'.$file)) {
$name = substr($file, 4, dol_strlen($file) - 16);
$classname = substr($file, 0, dol_strlen($file) - 12);
require_once $dir.'/'.$file;
$module = new $classname($db);
'@phan-var-force ModelePDFStockTransfer $module';
$modulequalified = 1;
if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
$modulequalified = 0;
if ($modulequalified) {
print '<tr class="oddeven"><td>';
print(empty($module->name) ? $name : $module->name);
print "</td><td>\n";
if (method_exists($module, 'info')) {
print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
} else {
print $module->description;
}
if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
$modulequalified = 0;
print '</td>';
// Active
if (in_array($name, $def)) {
print '<td class="center">'."\n";
print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.urlencode($name).'&token='.newToken().'">';
print img_picto($langs->trans("Enabled"), 'switch_on');
print '</a>';
print '</td>';
} else {
print '<td class="center">'."\n";
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&token='.newToken().'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
print "</td>";
}
if ($modulequalified) {
print '<tr class="oddeven"><td>';
print(empty($module->name) ? $name : $module->name);
print "</td><td>\n";
if (method_exists($module, 'info')) {
print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
} else {
print $module->description;
}
print '</td>';
// Active
if (in_array($name, $def)) {
print '<td class="center">'."\n";
print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.urlencode($name).'&token='.newToken().'">';
print img_picto($langs->trans("Enabled"), 'switch_on');
print '</a>';
print '</td>';
} else {
print '<td class="center">'."\n";
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&token='.newToken().'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
print "</td>";
}
// Default
print '<td class="center">';
$constforvar = strtoupper($myTmpObjectKey).'_ADDON_PDF';
if (getDolGlobalString($constforvar) == $name) {
print img_picto($langs->trans("Default"), 'on');
} else {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&object='.urlencode($myTmpObjectKey).'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
}
print '</td>';
// Info
$htmltooltip = ''.$langs->trans("Name").': '.$module->name;
$htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
if ($module->type == 'pdf') {
$htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
}
$htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
$htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
print '<td class="center">';
print $form->textwithpicto('', $htmltooltip, 1, 'info');
print '</td>';
// Preview
print '<td class="center">';
if ($module->type == 'pdf') {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'&object='.$myTmpObjectKey.'">'.img_object($langs->trans("Preview"), 'generic').'</a>';
} else {
print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
}
print '</td>';
print "</tr>\n";
// Default
print '<td class="center">';
$constforvar = strtoupper($myTmpObjectKey).'_ADDON_PDF';
if (getDolGlobalString($constforvar) == $name) {
print img_picto($langs->trans("Default"), 'on');
} else {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&object='.urlencode($myTmpObjectKey).'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
}
print '</td>';
// Info
$htmltooltip = ''.$langs->trans("Name").': '.$module->name;
$htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
if ($module->type == 'pdf') {
$htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
}
$htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
$htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
print '<td class="center">';
print $form->textwithpicto('', $htmltooltip, 1, 'info');
print '</td>';
// Preview
print '<td class="center">';
if ($module->type == 'pdf') {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'&object='.$myTmpObjectKey.'">'.img_object($langs->trans("Preview"), 'generic').'</a>';
} else {
print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
}
print '</td>';
print "</tr>\n";
}
}
}
@@ -491,14 +430,14 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
}
}
}
print '</table></div>';
}
print '</table></div>';
}
print '<br>';
print load_fiche_titre($langs->trans("OtherOptions", $myTmpObjectKey), '', '');
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">';
@@ -527,11 +466,6 @@ print '</td></tr>';
print '</table></div>';
if (empty($setupnotempty)) {
print '<br>'.$langs->trans("NothingToSetup");
}
// Page end
print dol_get_fiche_end();

View File

@@ -5,6 +5,7 @@
* Copyright (C) 2019 Christophe Battarel <christophe@altairis.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2025 Charlene Benke <charlene@patas-monkey.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,6 +60,7 @@ $default = 'ffffff';
$modules = [
'PROPAL' => array('lang' => 'propal', 'key' => 'Proposal', 'old_pdf' => '(azur model)'),
'COMMANDE' => array('lang' => 'orders', 'key' => 'CustomerOrder', 'old_pdf' => '(einstein model)'),
'FICHINTER' => array('lang' => 'interventions', 'key' => 'Intervention', 'old_pdf' => '(soleil model)'),
'FACTURE' => array('lang' => 'bills', 'key' => 'CustomerInvoice', 'old_pdf' => '(crabe model)'),
'FACTUREREC' => array('lang' => 'bills', 'key' => 'RecurringInvoiceTemplate'),
];
@@ -66,6 +68,7 @@ $modules = [
$conditions = [
'PROPAL' => isModEnabled("propal"),
'COMMANDE' => isModEnabled("order"),
'FICHINTER' => (isModEnabled("intervention")),
'FACTURE' => isModEnabled("invoice"),
'FACTUREREC' => isModEnabled("invoice"),
];

View File

@@ -28,8 +28,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -37,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
if (!$user->admin) {
accessforbidden();
@@ -332,7 +331,7 @@ print '</td></tr>';
if (!empty($conf->loghandlers['mod_syslog_file']) && isModEnabled('cron')) {
print '<tr class="oddeven"><td>'.$langs->trans("SyslogFileNumberOfSaves").'</td>';
print '<td colspan="2"><input class="width50" type="number" name="file_saves" placeholder="14" min="0" step="1" value="'.getDolGlobalString('SYSLOG_FILE_SAVES').'" />';
print ' &nbsp; (<a href="'.dol_buildpath('/cron/list.php', 1).'?search_label=CompressSyslogs&status=-1">'.$langs->trans('ConfigureCleaningCronjobToSetFrequencyOfSaves').'</a>)</td></tr>';
print ' &nbsp; <a href="'.dol_buildpath('/cron/list.php', 1).'?search_label=CompressSyslogs&status=-1">'.$langs->trans('ConfigureCleaningCronjobToSetFrequencyOfSaves').'</a></td></tr>';
}
print '</table>';

View File

@@ -121,7 +121,7 @@ if ($action == 'convertdynamic') {
llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-admin page-database_tables');
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database.php?restore_lastsearch_values=1">'.img_picto($langs->trans("Back"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("Back").'</span></a>';
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database.php?restore_lastsearch_values=1">'.img_picto($langs->trans("GoBack"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("GoBack").'</span></a>';
print load_fiche_titre($langs->trans("Tables")." ".ucfirst($conf->db->type), $linkback, 'title_setup');

View File

@@ -136,7 +136,7 @@ if ($action == 'convertutf8mb4') {
llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-admin page-system_dbtable');
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database-tables.php?restore_lastsearch_values=1">'.img_picto($langs->trans("Back"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("Back").'</span></a>';
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/system/database-tables.php?restore_lastsearch_values=1">'.img_picto($langs->trans("GoBack"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("GoBack").'</span></a>';
print load_fiche_titre($langs->trans("Table")." ".$table, $linkback, 'title_setup');

View File

@@ -26,12 +26,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
if (empty($user->admin)) {
accessforbidden();
}
/**
* @var Conf $conf
* @var DoliDB $db
@@ -39,6 +33,11 @@ if (empty($user->admin)) {
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
if (empty($user->admin)) {
accessforbidden();
}
// Load translation files required by the page
$langs->loadLangs(array("install", "other", "admin"));
@@ -52,6 +51,7 @@ $search_id = GETPOST("search_id", 'alpha');
$search_version = GETPOST("search_version", 'alpha');
$search_permission = GETPOST("search_permission", 'alpha');
$page = GETPOSTINT('page');
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');

View File

@@ -24,14 +24,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -43,7 +35,21 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
* @var string $conffile // $conffile is defined into filefunc.inc.php
* @var string $dolibarr_main_prod
* @var string $dolibarr_main_document_root
* @var string $dolibarr_main_restrict_os_commands
* @var string $dolibarr_main_restrict_eval_methods
* @var string $dolibarr_main_restrict_ip
* @var string $dolibarr_main_db_pass
* @var string $dolibarr_main_db_encrypted_pass
* @var string|string[] $dolibarr_main_stream_to_disable
* @var string $dolibarr_nocsrfcheck
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
// Load translation files required by the page
$langs->loadLangs(array("install", "other", "admin", "errors", "website"));
@@ -388,6 +394,15 @@ if (empty($dolibarr_main_restrict_os_commands)) {
print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pg_restore, mariadb, mariadb-dump, clamdscan').')</span>';
print '<br>';
print '<strong>$dolibarr_main_restrict_eval_methods</strong>: ';
if (empty($dolibarr_main_restrict_eval_methods)) {
print $langs->trans("None");
} else {
print $dolibarr_main_restrict_eval_methods;
}
print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'getDolGlobalString,getDolGlobalInt,getDolCurrency,fetchNoCompute,hasRight,isAdmin,isModEnabled,isStringVarMatching,abs,min,max,round,dol_now,dol_concat,preg_match').')</span>';
print '<br>';
if (!getDolGlobalString('SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF')) {
print '<strong>$dolibarr_main_db_pass</strong>: ';
if (!empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass)) {
@@ -816,7 +831,7 @@ if ($action == 'doldecrypt' && $user->admin && $exampletodecrypt) {
usleep(200);
$decryptedstring = dolDecrypt($exampletodecrypt);
if (ascii_check($decryptedstring)) {
print '<br> => <textarea rows="'.ROWS_1.'" class="valignmiddle">'.dolPrintHTMLForTextArea($decryptedstring).'</textarea>';
print '<br> => <textarea rows="'.ROWS_1.'" class="valignmiddle quatrevingtpercent">'.dolPrintHTMLForTextArea($decryptedstring).'</textarea>';
} else {
print '<br><span class="error"> => Failed to decrypt. The crypting key saved into the conf.php file seems to not be the one used to encrypt the provided encrypted string</span>';
}
@@ -965,16 +980,16 @@ print '<strong>MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES</strong> = '.(getDol
print ' &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").": 1 - does not work on HTML5 with some old libxml libs)</span><br>";
print '<br>';
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 1, disallow url links except if on /medias
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 2, disallow all external urls link
print '<strong>MAIN_DISALLOW_URL_INTO_DESCRIPTIONS</strong> = '.getDolGlobalString('MAIN_DISALLOW_URL_INTO_DESCRIPTIONS', '<span class="opacitymedium">'.$langs->trans("Undefined").' &nbsp; ('.$langs->trans("Recommended").': 1=only local links allowed or 2=no links at all)</span>')."<br>";
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 1, disallow url links except if on the local wrapper document.php or viewimage.php
// MAIN_DISALLOW_URL_INTO_DESCRIPTIONS = 2, disallow all urls link
print '<strong>MAIN_DISALLOW_URL_INTO_DESCRIPTIONS</strong> = '.getDolGlobalString('MAIN_DISALLOW_URL_INTO_DESCRIPTIONS', '<span class="opacitymedium">'.$langs->trans("Undefined").' &nbsp; ('.$langs->trans("Recommended").': 1=only local links allowed (to wrapper document.php or image.php) or 2=no links at all)</span>')."<br>";
print '<br>';
print '<strong>MAIN_ALLOW_SVG_FILES_AS_EXTERNAL_LINKS</strong> = '.getDolGlobalString('MAIN_ALLOW_SVG_FILES_AS_EXTERNAL_LINKS', '<span class="opacitymedium">'.$langs->trans("Undefined").' &nbsp; ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)</span>')."<br>";
print '<br>';
print '<strong>MAIN_DISALLOW_STRING_OBFUSCATION_IN_DOL_EVAL</strong> = '.(getDolGlobalString('MAIN_DISALLOW_STRING_OBFUSCATION_IN_DOL_EVAL') ? '1' : '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>');
print ' &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").": 1 - may break use of concatenation function like . or dol_concatdesc into extra fields conditions or formula)</span><br>";
print '<strong>MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL</strong> = '.getDolGlobalString('MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>');
print ' &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").": 0 - The value 1 allows the use of concatenation functions like . or dol_concat into extra fields conditions or formula but is not secured)</span><br>";
print '<br>';

View File

@@ -148,10 +148,9 @@ print "</script>\n";
$title = $langs->trans("Backup");
print load_fiche_titre($title, '', 'title_setup');
//print_barre_liste($langs->trans("Backup"), '', '', '', '', '', $langs->trans("BackupDesc",DOL_DATA_ROOT), 0, 0, 'title_setup');
print '<div class="center">';
print $langs->trans("BackupDesc", DOL_DATA_ROOT);
print $langs->trans("BackupDesc", 3);
print '</div>';
print '<br>';

View File

@@ -494,9 +494,9 @@ if ($result) {
$userstatic->email = $obj->email;
if (isModEnabled('multicompany') && $userstatic->admin && !$userstatic->entity) {
print img_picto($langs->trans("SuperAdministratorDesc"), 'redstar', 'class="valignmiddle paddingright"');
print img_picto($langs->trans("SuperAdministratorDesc"), 'superadmin', 'class="valignmiddle paddingright"');
} elseif ($userstatic->admin) {
print img_picto($langs->trans("AdministratorDesc"), 'star', 'class="valignmiddle paddingright"');
print img_picto($langs->trans("AdministratorDesc"), 'admin', 'class="valignmiddle paddingright"');
}
//print $userstatic->getLoginUrl(-1);

View File

@@ -87,7 +87,7 @@ class Documentation
// Go back to Dolibarr
$this->menu['BackToDolibarr'] = array(
'url' => DOL_URL_ROOT,
'url' => dol_buildpath('modulebuilder/index.php', 1),
'icon' => 'fas fa-arrow-left',
'submenu' => array(),
);
@@ -201,6 +201,13 @@ class Documentation
'submenu' => array(),
'summary' => array(),
),
'FreezeTooltip' => array(
'url' => dol_buildpath($this->baseUrl.'/content/freeze-tooltip.php', 1),
'icon' => 'far fa-comment',
'submenu' => array(),
'summary' => array(),
),
)
);
@@ -239,20 +246,40 @@ class Documentation
'ExperimentalUxContributionTitle' => '#experimental-ux-contribution',
),
),
'ExperimentalUxFreezeTooltip' => array(
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/freeze-tooltip/index.php', 1),
'icon' => 'fas fa-flask',
'submenu' => array(),
'summary' => array(),
),
'ExperimentalUxInputAjaxFeedback' => array(
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/input-feedback/index.php', 1),
'icon' => 'fas fa-flask',
'submenu' => array(),
'summary' => array(),
),
'UxDolibarrContext' => array(
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/dolibarr-context/index.php', 1),
'icon' => 'fas fa-flask',
'submenu' => array(
'UxDolibarrContextHowItWork' => array(
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/dolibarr-context/index.php', 1),
'icon' => 'fas fa-flask',
'submenu' => array(),
'summary' => array(
'Introduction' => '#titlesection-basicusage',
'ConsoleHelp' => '#titlesection-console-help',
'JSDolibarrhooks' => '#titlesection-hooks',
'JSDolibarrhooksReadyVsInit' => '#titlesection-event-init-vs-ready',
'JSDolibarrAwaitHooks' => '#titlesection-await-hooks',
'ExampleOfCreatingNewContextTool' => '#titlesection-create-tool-example',
'SetEventMessageTool' => '#titlesection-tool-seteventmessage',
'SetAndUseContextVars' => '#titlesection-contextvars',
),
),
'UxDolibarrContextLangsTool' => array(
'url' => dol_buildpath($this->baseUrl.'/experimental/experiments/dolibarr-context/langs-tool.php', 1),
'icon' => 'fas fa-flask',
'submenu' => array(),
'summary' => array(),
),
),
'summary' => array(),
),
)
);
@@ -471,7 +498,13 @@ class Documentation
if ($showsubmenu && !empty($menu['submenu'])) {
foreach ($menu['submenu'] as $key => $item) {
print '<li class="summary-title ">';
if (!empty($item['url'])) {
print '<h3 class="level-'.$level.'"><a href="'.dolBuildUrl($item['url']).'" >'.$langs->trans($key).'</a></h3>';
} else {
print '<h3 class="level-'.$level.'">'.$langs->trans($key).'</h3>';
}
if ($showsubmenu_summary) {
$this->displaySummary($item, $level);
}

View File

@@ -18,7 +18,7 @@
*/
// Load Dolibarr environment
require '../../../../../../main.inc.php';
require '../../../../main.inc.php';
/**
* @var DoliDB $db
@@ -40,22 +40,20 @@ $langs->load('uxdocumentation');
//
$documentation = new Documentation($db);
$group = 'ExperimentalUx';
$experimentAssetsPath = $documentation->baseUrl . '/experimental/experiments/freeze-tooltip/assets/';
$group = 'Content';
$js = [
$experimentAssetsPath . 'freeze-by-alt-keypress.js'
// now included in Dolibarr in htdocs/core/js/lib_tooltip-freeze-by-alt-keypress.js
];
$css = [
$experimentAssetsPath . 'freeze-by-alt-keypress.css'
// now included in Dolibarr in htdocs/theme/eldy/tooltips.inc.css
];
// Output html head + body - Param is Title
$documentation->docHeader($langs->trans('ExperimentalUxFreezeTooltip', $group), $js, $css);
$documentation->docHeader($langs->trans('FreezeTooltip', $group), $js, $css);
// Set view for menu and breadcrumb
$documentation->view = [$group, 'ExperimentalUxFreezeTooltip'];
$documentation->view = [$group, 'FreezeTooltip'];
// Output sidebar
$documentation->showSidebar(); ?>
@@ -66,7 +64,7 @@ $documentation->showSidebar(); ?>
<div class="doc-content-wrapper">
<h1 class="documentation-title"><?php echo $langs->trans('ExperimentalUxFreezeTooltip'); ?></h1>
<h1 class="documentation-title"><?php echo $langs->trans('FreezeTooltip'); ?></h1>
<?php $documentation->showSummary(); ?>
@@ -142,4 +140,3 @@ $documentation->showSidebar(); ?>
<?php
// Output close body + html
$documentation->docFooter();
?>

View File

@@ -0,0 +1,171 @@
/** This file is purely for IDE autocompletion and developer convenience.
* It is never executed or loaded in Dolibarr itself.
*
* MOCK DEFINITION: Dolibarr.tools
* This mock helps your code editor understand the structure of Dolibarr.tools
* and provides autocomplete hints, parameter hints, and inline documentation.
* You can safely edit this file to add all standard Dolibarr tools for autocompletion.
*
* @SEE dolibarr-context.umd.js
*
*/
var Dolibarr = {
tools: {
/**
* Displays a Dolibarr notification message (success, warning, or error).
* This is the JavaScript equivalent of the PHP setEventMessage tool.
*
* @param {string} msg The message text to display
* @param {string=} type Optional: 'mesgs' (default), 'warnings', or 'errors'
* @param {boolean=} sticky Optional: true if the message should stay until manually closed
*
* Example usage in your IDE:
* Dolibarr.tools.setEventMessage('Operation successful', 'success');
*/
setEventMessage: function(msg, type, sticky) {},
/**
* TThe langs tool
*/
langs: {
/**
* Load a single locale from cache or fetch
* @param {string} domain
* @param {string} locale
* @returns {Promise<Object>} translation object
*/
loadLocale(domain, locale) {},
/**
* Load translations for a domain (multiple locales)
* @param {string} domain
* @param {string} locales - comma-separated list
* @returns {Promise<Object>}
*/
load(domain, locales = currentLocale) {},
/**
* Set the current locale to use for translations
* @param {string} locale
*/
setLocale(locale) {},
/**
* Translate a key using current locale
* Supports placeholders like %s, %d, %f (simple sprintf)
* @param {string} key
* @param {...any} args
* @returns {string}
*/
trans(key, ...args) {},
},
// You can add more standard Dolibarr tools here for IDE autocompletion.
// Example:
// alertUser: function(msg) {},
},
/**
* Defines a new secure tool.
* @param {string} name Name of the tool
* @param {*} value Function, class or object
* @param {boolean} overwrite Explicitly allow overwriting an existing tool
*
* See also dolibarr-context.mock.js for defining all standard Dolibarr tools and creating mock implementations to improve code completion and editor support.
*/
defineTool(name, value, overwrite = false, triggerHook = true) {},
/**
* Check if tool exists
* @param {string} name Tool name
* @returns {boolean} true if exists
*/
checkToolExist(name) {},
/**
* Get read-only snapshot of context variables
*/
ContextVars() {},
/**
* Defines a new context variable.
* @param {string} key
* @param {string|number|boolean} value
* @param {boolean} overwrite Allow overwriting existing value
*/
setContextVar(key, value, overwrite = false) {},
/**
* Set multiple context variables
* @param {Object} vars Object of key/value pairs
* @param {boolean} overwrite Allow overwriting existing values
*/
setContextVars(vars, overwrite = false) {},
/**
* Get a context variable safely
* @param {string} key
* @param {*} fallback Optional fallback if variable not set
* @returns {*}
*/
getContextVar(key, fallback = null) {},
/**
* Enable or disable debug mode
* @param {boolean} state
*/
debugMode(state) {},
/**
* Enable or disable debug mode
* @returns {int}
*/
getDebugMode() {},
/**
* Internal logger
* Only prints when debug mode is enabled
* @param {string} msg
*/
log(msg) {},
/**
* Executes a hook-like JS event with CustomEvent.
* @param {string} hookName Hook identifier
* @param {object} data Extra information passed to listeners
*/
executeHook(hookName, data = {}) {},
/**
* Registers an event listener.
* @param {string} eventName Event to listen to
* @param {function} callback Listener function
*/
on(eventName, callback) {},
/**
* Unregister an event listener
* @param {string} eventName
* @param {function} callback
*/
off(eventName, callback) {},
/**
* Register an asynchronous hook
* @param {string} eventName
* @param {function} fn Async function receiving previous result
* @param {Object} opts Optional {before, after, id} to control order
* @returns {string} The hook ID
*/
onAwait(eventName, fn, opts = {}) {},
/**
* Execute async hooks sequentially
* @param {string} eventName
* @param {*} data Input data for first hook
* @returns {Promise<*>} Final result after all hooks
*/
async executeHookAwait(eventName, data) {},
};

View File

@@ -0,0 +1,443 @@
// CustomEvent doesnt show up until IE 11 and Safari 10. Fortunately a simple polyfill pushes support back to any IE 9.
(function () {
if ( typeof window.CustomEvent === "function" ) return false;
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
// End old browsers support
/**
* Dolibarr Global Context (UMD)
* Provides a secure global object window.Dolibarr
* with non-replaceable tools, events and debug mode.
*
* See also dolibarr-context.mock.js for defining all standard Dolibarr tools and creating mock implementations to improve code completion and editor support.
*
*/
(function (root, factory) {
// Support AMD
if (typeof define === "function" && define.amd) {
define([], factory);
// Support CommonJS (Node, bundlers)
} else if (typeof exports === "object") {
module.exports = factory();
// Fallback global (browser)
} else {
root.Dolibarr = root.Dolibarr || factory();
}
})(typeof self !== "undefined" ? self : this, function () {
// Prevent double initialization if script loaded twice
if (typeof window !== "undefined" && window.Dolibarr) {
return window.Dolibarr;
}
// Private storage for secure tools (non-replaceable)
const _tools = {};
// Private storage for secure context vars or constants (non-replaceable)
const _contextVars = {};
// Internal map to track proxies for events
const _proxies = new Map();
// Native event dispatcher (standard DOM)
const _events = new EventTarget();
const _awaitHooks = {}; // Async hooks storage
// Debug flag (disabled by default)
let _debug = false;
// -------------------------
// Internal helper functions
// -------------------------
function _ensureEvent(name) { if (!_awaitHooks[name]) _awaitHooks[name] = []; }
function _generateId() { return 'hook_' + Math.random().toString(36).slice(2); }
function _idExists(name, id) { return _awaitHooks[name].some(h => h.id === id); }
/**
* Insert a new hook entry in the array respecting optional before/after lists
*/
function _insertWithOrder(arr, entry, beforeList, afterList) {
if ((!beforeList || beforeList.length === 0) && (!afterList || afterList.length === 0)) {
arr.push(entry);
return arr;
}
let ordered = [...arr];
let index = ordered.length;
if (beforeList && beforeList.length > 0) {
for (const target of beforeList) {
const i = ordered.findIndex(h => h.id === target);
if (i !== -1 && i < index) index = i;
}
}
if (afterList && afterList.length > 0) {
for (const target of afterList) {
const i = ordered.findIndex(h => h.id === target);
if (i !== -1 && i >= index) index = i + 1;
}
}
if (index > ordered.length) index = ordered.length;
ordered.splice(index, 0, entry);
return ordered;
}
// -------------------------
// Dolibarr object
// -------------------------
const Dolibarr = {
/**
* Returns a frozen copy of the registered tools.
* Tools cannot be modified or replaced from outside.
*/
get tools() {
return Object.freeze({ ..._tools });
},
/**
* Defines a new secure tool.
* @param {string} name Name of the tool
* @param {*} value Function, class or object
* @param {boolean} overwrite Explicitly allow overwriting an existing tool
*
* See also dolibarr-context.mock.js for defining all standard Dolibarr tools and creating mock implementations to improve code completion and editor support.
*/
defineTool(name, value, overwrite = false, triggerHook = true) {
// Prevent silent overrides unless "overwrite" is true
if (!overwrite && this.checkToolExist(name)) {
throw new Error(`Dolibarr: Tool '${name}' already defined`);
}
// Define the tool as read-only and non-configurable
Object.defineProperty(_tools, name, {
value,
writable: false,
configurable: false,
enumerable: true,
});
this.log(`Tool defined: ${name}, triggerHook: ${triggerHook}, overwrite: ${overwrite} `);
if(triggerHook) {
this.executeHook('defineTool', { toolName: name, overwrite });
}
},
/**
* Check if tool exists
* @param {string} name Tool name
* @returns {boolean} true if exists
*/
checkToolExist(name) {
return Object.prototype.hasOwnProperty.call(_tools, name);
},
/**
* Get read-only snapshot of context variables
*/
get ContextVars() {
return Object.freeze({ ..._contextVars });
},
/**
* Defines a new context variable.
* @param {string} key
* @param {string|number|boolean} value
* @param {boolean} overwrite Allow overwriting existing value
*/
setContextVar(key, value, overwrite = false) {
// Accept only string, number, or boolean
const type = typeof value;
if (type !== 'string' && type !== 'number' && type !== 'boolean') {
throw new TypeError(`Dolibarr: ContextVar '${key}' must be a string, number, or boolean`);
}
if (!overwrite && _contextVars.hasOwnProperty(key)) {
throw new Error(`Dolibarr: ContextVar '${key}' already defined`);
}
Object.defineProperty(_contextVars, key, {
value,
writable: false,
configurable: false,
enumerable: true
});
this.log(`ContextVar set: ${key} = ${value} (overwrite: ${overwrite})`);
this.executeHook('setContextVar', { key, value, overwrite });
},
/**
* Set multiple context variables
* @param {Object} vars Object of key/value pairs
* @param {boolean} overwrite Allow overwriting existing values
*/
setContextVars(vars, overwrite = false) {
if (typeof vars !== 'object' || vars === null) {
throw new Error('Dolibarr: setContextVars expects an object');
}
for (const [key, value] of Object.entries(vars)) {
this.setContextVar(key, value, overwrite);
}
},
/**
* Get a context variable safely
* @param {string} key
* @param {*} fallback Optional fallback if variable not set
* @returns {*}
*/
getContextVar(key, fallback = null) {
return _contextVars.hasOwnProperty(key) ? _contextVars[key] : fallback;
},
/**
* Enable or disable debug mode
* @param {boolean} state
*/
debugMode(state) {
_debug = !!state;
// save in localStorage
if (typeof window !== "undefined" && window.localStorage) {
localStorage.setItem('DolibarrDebugMode', _debug ? '1' : '0');
}
this.log(`Debug mode: ${_debug}`);
},
/**
* Enable or disable debug mode
* @returns {int}
*/
getDebugMode() {
return _debug ? 1 : 0
},
/**
* Internal logger
* Only prints when debug mode is enabled
* @param {string} msg
*/
log(msg) {
if (_debug) console.log(`Dolibarr: ${msg}`);
},
/**
* Executes a hook-like JS event with CustomEvent.
* @param {string} hookName Hook identifier
* @param {object} data Extra information passed to listeners
*/
executeHook(hookName, data = {}) {
this.log(`Hook executed: ${hookName}`);
const ev = new CustomEvent(hookName, { detail: data });
// Dispatch on internal EventTarget
_events.dispatchEvent(ev);
// Dispatch globally on document for backward compatibility
if (typeof document !== "undefined") {
document.dispatchEvent(new CustomEvent('Dolibarr:' + hookName, { detail: data }));
}
// Notify Dolibarr.on() listeners with data directly
const listeners = _events.listeners?.[hookName] || [];
listeners.forEach(fn => fn(data));
},
/**
* Registers an event listener.
* @param {string} eventName Event to listen to
* @param {function} callback Listener function
*/
on(eventName, callback) {
// Create a proxy to extract e.detail
const proxy = function(e) {
callback(e.detail);
};
// Store the proxy so we can remove it later
if (!_proxies.has(eventName)) _proxies.set(eventName, new Map());
_proxies.get(eventName).set(callback, proxy);
// Attach proxy to the internal EventTarget
_events.addEventListener(eventName, proxy);
},
/**
* Unregister an event listener
* @param {string} eventName
* @param {function} callback
*/
off(eventName, callback) {
const map = _proxies.get(eventName);
if (!map) return;
const proxy = map.get(callback);
if (!proxy) return;
// Remove proxy from EventTarget
_events.removeEventListener(eventName, proxy);
map.delete(callback);
// Cleanup if no proxies remain for this event
if (map.size === 0) _proxies.delete(eventName);
},
/**
* Register an asynchronous hook
* @param {string} eventName
* @param {function} fn Async function receiving previous result
* @param {Object} opts Optional {before, after, id} to control order
* @returns {string} The hook ID
*/
onAwait(eventName, fn, opts = {}) {
_ensureEvent(eventName);
let id = opts.id || _generateId();
if (_idExists(eventName, id)) throw new Error(`onAwait: ID '${id}' already used for '${eventName}'`);
const before = Array.isArray(opts.before) ? opts.before : (opts.before ? [opts.before] : []);
const after = Array.isArray(opts.after) ? opts.after : (opts.after ? [opts.after] : []);
_awaitHooks[eventName] = _insertWithOrder(_awaitHooks[eventName], { id, fn }, before, after);
return id;
},
/**
* Execute async hooks sequentially
* @param {string} eventName
* @param {*} data Input data for first hook
* @returns {Promise<*>} Final result after all hooks
*/
async executeHookAwait(eventName, data) {
this.log(`Await Hook executed: ${eventName}`);
_ensureEvent(eventName);
let result = data;
for (const h of _awaitHooks[eventName]) {
result = await h.fn(result);
}
return result;
}
};
// Lock Dolibarr core object
Object.freeze(Dolibarr);
// Expose Dolibarr to window in a protected, non-writable way
if (typeof window !== "undefined") {
Object.defineProperty(window, "Dolibarr", {
value: Dolibarr,
writable: false,
configurable: false,
enumerable: true,
});
}
// Restore debug mode from localStorage
if (typeof window !== "undefined" && window.localStorage) {
const saved = localStorage.getItem('DolibarrDebugMode');
if (saved === '1') {
Dolibarr.debugMode(true);
}
}
// Force initialise hook init and Ready in good execution order
(function triggerDolibarrHooks() {
// Fire Init first
const fireInit = () => {
Dolibarr.executeHook('Init', { context: Dolibarr });
Dolibarr.log('Context Init done');
// Only after Init is done, fire Ready
fireReady();
};
const fireReady = () => {
Dolibarr.executeHook('Ready', { context: Dolibarr });
Dolibarr.log('Context Ready done');
};
if (document.readyState === 'complete' || document.readyState === 'interactive') {
// DOM already ready, trigger Init -> Ready in order
fireInit();
} else {
// Wait for DOM ready, then trigger Init -> Ready
document.addEventListener('DOMContentLoaded', fireInit);
}
})();
/**
* Display help in console log
*/
Dolibarr.defineTool('showConsoleHelp', () => {
console.groupCollapsed(
"%cDolibarr JS Developers HELP",
"background-color: #95cf04; color: #ffffff; font-weight: bold; padding: 4px;"
);
console.log("Show this help : %cDolibarr.tools.showConsoleHelp();","font-weight: bold;");
console.log(`Documentation for admin only on : %cModule builder ➜ UX Components Doc`,"font-weight: bold;");
// DEBUG MODE
console.groupCollapsed("Dolibarr debug mode");
console.log(
"When help was displayed, status was: %c" + (Dolibarr.getDebugMode() ? "ENABLED" : "DISABLED"),
"font-weight: bold; color:" + (Dolibarr.getDebugMode() ? "green" : "red") + ";"
);
console.log(
"Activate debug mode : %cDolibarr.debugMode(true);",
"font-weight: bold;"
);
console.log(
"Disable debug mode : %cDolibarr.debugMode(false);",
"font-weight: bold;"
);
console.log("Note : debug mode status is persistent.");
console.groupEnd();
// HOOKS
console.groupCollapsed("Hooks helpers");
console.log(
"Run a hook manually : %cDolibarr.executeHook('hookName', {...})",
"font-weight: bold;"
);
console.log(
"Run await hooks manually : %cawait Dolibarr.executeHookAwait('hookName', {...})",
"font-weight: bold;"
);
console.groupEnd();
console.groupEnd(); // END MAIN GROUP
}, false, false);
// Auto-show help when console is opened
Dolibarr.tools.showConsoleHelp();
return Dolibarr;
});

View File

@@ -0,0 +1,232 @@
document.addEventListener('Dolibarr:Init', function(e) {
/**
* Dolibarr.tools.langs
* --------------------
* Manage translations in JS context with IndexedDB cache, multi-locale support and fallback.
* Parallel loading of language files for performance.
* Automatic cache invalidation if Dolibarr version changes.
*
* Require Dolibarr context vars
* DOL_LANG_INTERFACE_URL, MAIN_LANG_DEFAULT, DOL_VERSION
*
*/
const langs = function() {
const ONE_DAY = 86400000;
let currentLocale = Dolibarr.getContextVar('MAIN_LANG_DEFAULT', 'en_US');
let translations = {}; // { en_US: {KEY: TEXT}, fr_FR: {...} }
let domainsLoaded = {}; // { en_US: Set(['main','other']), fr_FR: Set([...]) }
if (!domainsLoaded[currentLocale]) domainsLoaded[currentLocale] = new Set();
let domainsRequested = new Set(); // Set of domain names that were requested at least once
/**
* Open or create IndexedDB for caching translations
* @returns {Promise<IDBDatabase>}
*/
async function openDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('DolibarrLangs', 1);
request.onupgradeneeded = e => {
const db = e.target.result;
if (!db.objectStoreNames.contains('langs')) db.createObjectStore('langs');
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
/**
* Get cached translation for a domain + locale
* @param {string} domain
* @param {string} locale
* @returns {Promise<Object|null>}
*/
async function getCache(domain, locale) {
try {
const db = await openDB();
const tx = db.transaction('langs', 'readonly');
const store = tx.objectStore('langs');
return new Promise((resolve, reject) => {
const request = store.get(`${domain}@${locale}`);
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
} catch (err) {
return null;
}
}
/**
* Set cached translation for a domain + locale
* @param {string} domain
* @param {string} locale
* @param {Object} data
*/
async function setCache(domain, locale, data) {
try {
const db = await openDB();
const tx = db.transaction('langs', 'readwrite');
const store = tx.objectStore('langs');
const dolibarrVersion = Dolibarr.getContextVar('DOL_VERSION', 0);
await store.put({ key: `${domain}@${locale}`, data, timestamp: Date.now(), dolibarrVersion }, `${domain}@${locale}`);
} catch (err) {
// fail silently
Dolibarr.log('Save langs in cache fail');
}
}
/**
* Clear all cached translations in IndexedDB and in-memory
*/
async function clearCache(clearMemory = false) {
if(clearMemory) {
translations = {};
domainsLoaded = {};
}
try {
const db = await openDB();
const tx = db.transaction('langs', 'readwrite');
const store = tx.objectStore('langs');
await store.clear();
Dolibarr.log('Dolibarr.tools.langs: cache cleared');
} catch (err) {
console.error('Dolibarr.tools.langs: failed to clear cache', err);
}
}
/**
* Load a single locale from cache or fetch
* @param {string} domain
* @param {string} locale
* @returns {Promise<Object>} translation object
*/
async function loadLocale(domain, locale) {
const cache = await getCache(domain, locale);
const now = Date.now();
const dolibarrVersion = Dolibarr.getContextVar('DOL_VERSION', 0);
if (cache && cache.data && (now - cache.timestamp < ONE_DAY) && cache.dolibarrVersion === dolibarrVersion) {
Dolibarr.log('Langs tool : Load lang from cache');
return cache.data;
}
const langInterfaceUrl = Dolibarr.getContextVar('DOL_LANG_INTERFACE_URL', false);
if(!langInterfaceUrl) {
console.error('Dolibarr langs: missing DOL_LANG_INTERFACE_URL')
return;
}
Dolibarr.log('Langs tool : Load lang from interface');
const params = new URLSearchParams({ domain, local: locale });
const resp = await fetch(`${langInterfaceUrl}?${params.toString()}`);
const json = await resp.json();
const data = json[locale] || {};
await setCache(domain, locale, data);
return data;
}
/**
* Load translations for a domain (multiple locales)
* @param {string} domain
* @param {string} locales - comma-separated list
* @returns {Promise<Object>}
*/
async function load(domain, locales = currentLocale) {
const list = locales.split(',');
// flag domaine as requested for future load when local change
domainsRequested.add(domain);
const results = await Promise.all(list.map(loc => loadLocale(domain, loc)));
list.forEach((loc, i) => {
if (!translations[loc]) translations[loc] = {};
Object.assign(translations[loc], results[i]);
if (!domainsLoaded[loc]) domainsLoaded[loc] = new Set();
domainsLoaded[loc].add(domain);
});
return translations;
}
/**
* Set the current locale to use for translations
* @param {string} locale
*/
async function setLocale(locale, noDomainReload = false) {
if (!locale || locale === currentLocale) return;
const prev = currentLocale;
currentLocale = locale;
if (!domainsLoaded[locale]) domainsLoaded[locale] = new Set();
if (!noDomainReload) {
// priorité : domainsLoaded[prev], sinon fallback sur domainsRequested
let toReload = Array.from(domainsLoaded[prev] || []);
if (toReload.length === 0) {
// aucun domaine marqué comme "loaded" pour prev : utiliser la liste des domaines demandés
toReload = Array.from(domainsRequested);
}
for (const domain of toReload) {
// load(domain, locale) accepte le param locale ; l'appel charge et met domainsLoaded
if (domainsLoaded[locale].size === 0) {
await load(domain, locale);
}
}
}
Dolibarr.log(`Locale changed: ${prev} -> ${locale}`);
}
/**
* Translate a key using current locale
* Supports placeholders like %s, %d, %f (simple sprintf)
* @param {string} key
* @param {...any} args
* @returns {string}
*/
function trans(key, ...args) {
const text = translations[currentLocale]?.[key] || key;
if (!args.length) return text;
// Utilisation de la fonction sprintf pour le formatage
return sprintf(text, ...args);
}
function sprintf(fmt, ...args) {
let i = 0;
return fmt.replace(/%[%bcdeEfFgGosuxX]/g, (match) => {
if (match === '%%') return '%';
const arg = args[i++];
switch (match) {
case '%s': return String(arg);
case '%d':
case '%u': return Number(arg);
case '%f':
case '%F': return parseFloat(arg);
case '%b': return Number(arg).toString(2);
case '%o': return Number(arg).toString(8);
case '%x': return Number(arg).toString(16);
case '%X': return Number(arg).toString(16).toUpperCase();
case '%c': return String.fromCharCode(Number(arg));
default: return match;
}
});
}
return {
load,
clearCache,
setLocale,
trans,
get currentLocale() { return currentLocale; }
};
};
Dolibarr.defineTool('langs',langs());
});

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