Ver código fonte

Merge branch 'develop' into loaddolibarrenv

Laurent Destailleur 2 anos atrás
pai
commit
7a277d9560
100 arquivos alterados com 1472 adições e 502 exclusões
  1. 1 0
      COPYRIGHT
  2. 24 24
      ChangeLog
  3. 1 1
      htdocs/accountancy/journal/variousjournal.php
  4. 2 2
      htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php
  5. 15 15
      htdocs/adherents/card.php
  6. 3 3
      htdocs/adherents/class/api_members.class.php
  7. 1 1
      htdocs/adherents/class/api_subscriptions.class.php
  8. 4 4
      htdocs/adherents/document.php
  9. 2 2
      htdocs/adherents/ldap.php
  10. 6 6
      htdocs/adherents/list.php
  11. 4 4
      htdocs/adherents/note.php
  12. 4 4
      htdocs/adherents/subscription.php
  13. 1 1
      htdocs/adherents/type.php
  14. 2 2
      htdocs/adherents/vcard.php
  15. 2 2
      htdocs/admin/clicktodial.php
  16. 4 4
      htdocs/admin/fichinter.php
  17. 1 1
      htdocs/admin/hrm.php
  18. 3 3
      htdocs/admin/reception_setup.php
  19. 1 1
      htdocs/admin/supplier_invoice.php
  20. 55 53
      htdocs/admin/supplier_order.php
  21. 6 6
      htdocs/admin/supplier_payment.php
  22. 3 2
      htdocs/admin/ticket.php
  23. 8 8
      htdocs/admin/ticket_public.php
  24. 10 5
      htdocs/admin/tools/purge.php
  25. 2 0
      htdocs/api/index.php
  26. 4 4
      htdocs/categories/class/api_categories.class.php
  27. 13 13
      htdocs/categories/viewcat.php
  28. 16 12
      htdocs/comm/action/card.php
  29. 0 4
      htdocs/comm/action/list.php
  30. 43 26
      htdocs/comm/action/pertype.php
  31. 3 0
      htdocs/compta/bank/annuel.php
  32. 1 1
      htdocs/compta/bank/bankentries_list.php
  33. 6 4
      htdocs/compta/bank/transfer.php
  34. 1 1
      htdocs/compta/bank/treso.php
  35. 2 0
      htdocs/compta/paiement/cheque/list.php
  36. 2 1
      htdocs/compta/prelevement/create.php
  37. 2 0
      htdocs/compta/prelevement/orders_list.php
  38. 2 2
      htdocs/core/actions_linkedfiles.inc.php
  39. 6 3
      htdocs/core/ajax/objectonoff.php
  40. 1 3
      htdocs/core/ajax/onlineSign.php
  41. 1 0
      htdocs/core/ajax/selectsearchbox.php
  42. 809 0
      htdocs/core/class/commoninvoice.class.php
  43. 1 0
      htdocs/core/class/html.formticket.class.php
  44. 24 12
      htdocs/core/class/utils.class.php
  45. 1 1
      htdocs/core/db/mysqli.class.php
  46. 21 17
      htdocs/core/lib/files.lib.php
  47. 2 1
      htdocs/core/lib/functions.lib.php
  48. 35 5
      htdocs/core/lib/security.lib.php
  49. 2 2
      htdocs/core/modules/commande/mod_commande_saphir.php
  50. 2 2
      htdocs/core/modules/contract/mod_contract_magre.php
  51. 2 2
      htdocs/core/modules/fichinter/mod_arctic.php
  52. 3 1
      htdocs/core/modules/modZapier.class.php
  53. 2 2
      htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
  54. 2 2
      htdocs/core/modules/reception/mod_reception_moonstone.php
  55. 11 11
      htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
  56. 2 2
      htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
  57. 4 4
      htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
  58. 3 3
      htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
  59. 2 2
      htdocs/core/modules/ticket/mod_ticket_universal.php
  60. 1 3
      htdocs/core/tpl/login.tpl.php
  61. 1 3
      htdocs/core/tpl/passwordforgotten.tpl.php
  62. 25 1
      htdocs/core/website.inc.php
  63. 4 4
      htdocs/document.php
  64. 0 1
      htdocs/eventorganization/conferenceorboothattendee_note.php
  65. 38 1
      htdocs/fourn/commande/list.php
  66. 1 1
      htdocs/hrm/admin/admin_establishment.php
  67. 1 1
      htdocs/hrm/establishment/card.php
  68. 0 1
      htdocs/hrm/position.php
  69. 7 6
      htdocs/hrm/skill_card.php
  70. 3 1
      htdocs/hrm/skill_tab.php
  71. 2 1
      htdocs/langs/en_US/errors.lang
  72. 8 5
      htdocs/main.inc.php
  73. 2 2
      htdocs/modulebuilder/index.php
  74. 1 5
      htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php
  75. 0 1
      htdocs/modulebuilder/template/myobject_agenda.php
  76. 1 3
      htdocs/modulebuilder/template/myobject_card.php
  77. 91 92
      htdocs/modulebuilder/template/myobject_document.php
  78. 0 1
      htdocs/modulebuilder/template/myobject_list.php
  79. 0 1
      htdocs/modulebuilder/template/myobject_note.php
  80. 0 1
      htdocs/modulebuilder/template/scripts/mymodule.php
  81. 7 4
      htdocs/mrp/mo_card.php
  82. 9 6
      htdocs/multicurrency/multicurrency_rate.php
  83. 6 5
      htdocs/opensurvey/card.php
  84. 7 5
      htdocs/opensurvey/exportcsv.php
  85. 10 9
      htdocs/product/card.php
  86. 17 1
      htdocs/projet/class/projectstats.class.php
  87. 1 1
      htdocs/public/agenda/agendaexport.php
  88. 1 1
      htdocs/public/cron/cron_run_jobs_by_url.php
  89. 1 1
      htdocs/public/demo/index.php
  90. 1 1
      htdocs/public/donations/donateurs_code.php
  91. 1 1
      htdocs/public/eventorganization/attendee_new.php
  92. 1 1
      htdocs/public/eventorganization/subscriptionok.php
  93. 2 3
      htdocs/public/members/new.php
  94. 1 1
      htdocs/public/members/public_card.php
  95. 1 1
      htdocs/public/members/public_list.php
  96. 15 19
      htdocs/public/onlinesign/newonlinesign.php
  97. 5 5
      htdocs/public/opensurvey/studs.php
  98. 2 3
      htdocs/public/partnership/new.php
  99. 1 1
      htdocs/public/payment/paymentko.php
  100. 1 1
      htdocs/public/payment/paymentok.php

+ 1 - 0
COPYRIGHT

@@ -33,6 +33,7 @@ PEAR Mail_MIME         1.8.9         BSD                         Yes
 ParseDown              1.6           MIT License                 Yes             Markdown parser
 PCLZip                 2.8.4         LGPL-3+                     Yes             Library to zip/unzip files             
 PHPDebugBar            1.15.1        MIT License                 Yes             Used only by the module "debugbar" for developers
+PHP-Imap               2.7.2         MIT License                 Yes             Library to use IMAP with OAuth
 PHPSpreadSheet         1.8.2         LGPL-2.1+                   Yes             Read/Write XLS files, read ODS files
 php-iban               4.1           LGPL-3+                     Yes             Parse and validate IBAN (and IIBAN) bank account information in PHP
 PHPoAuthLib            0.8.2         MIT License                 Yes             Library to provide oauth1 and oauth2 to different service

+ 24 - 24
ChangeLog

@@ -59,66 +59,60 @@ NEW: Add margin info in proposal and order list
 NEW: Add massaction "Edit Extrafield" for Product
 NEW: Add more fields to detect duplicate during import of thirdparties
 NEW: Add option to foce delivery on email for purchase order receipt to yes
-NEW: Add param boder table for md theme
+NEW: Add param border table for md theme
 NEW: Add param color button action
 NEW: Add possibility to create contract from invoice
 NEW: Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad character unauthorized into login name
 NEW: Add private and public notes on tax files.
-NEW: Add status "Obsolete" to KM articles
 NEW: Add substitutions "user numbers"
 NEW: allow a ticket to be automatically marked as read when created from backend.
 NEW: allow cut&paste as real numeric value to excel
 NEW: A public form to send a message and create a lead is available
 NEW: automatically set totally received status in reception
 NEW: Auto set invoice paid when adding credit not and remain to pay is 0
-NEW: Availibility dictionnary has a new column unit and number
 NEW: Can change value of AWP during the inventory
 NEW: Can enter price with tax for predefined products on purchase objects
 NEW: Can filter on a thirdparty on product statistics
 NEW: Can removed doc templates from setup page of thirdparty
-NEW: Can set the parent company during the creation of thirdparty (action=add of societe/card.php)
 NEW: Can use ! to make a search that exclude a string
 NEW: Change in theme colors does not need to use the refresh button
 NEW: clean values and amount in FEC import
 NEW: const MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND for mailing mass action
 NEW: Contact filter project list
 NEW: Create contract from invoice
-NEW: create third-party with contact if not found on public ticket
+NEW: Database: Can store the session into database (instead of beeing managed by PHP)
+NEW: Database: Some core tables are created only at module activation
 NEW: Default value for MAIN_SECURITY_CSRF_WITH_TOKEN is now 2 (GET are also protected agains CSRF attacks)
 NEW: deposit payment terms: add field into dictionary admin page to define default percentage of deposit. 
 NEW: Dictionaries - add possibility to manage countries in EEC
+NEW: Dictionaries - Availibility dictionnary has a new column unit and number
 NEW: Display errors in a message box after generating documents
-NEW: Display physical and virtual stock of the products when creating OF from a BOM
-NEW: Display product ref in "Object link" product tab for BOM
 NEW: Enhance the import. Can use 'auto' for the ref (import of orders)
 NEW: Events on Proposal to Return to Draft
 NEW: Page to list expense report payments
 NEW: JS inventory autocalc input
 NEW: language support for more emailing target selectors
 NEW: leave requests: add field into type dictionary to block request if balance is negative
-NEW: MAIN_MAIL_AUTOCOPY_TO can accept several email and special keys
-NEW: MAIN_SEARCH_CAT_OR_BY_DEFAULT const for search by category
 NEW: Mass action "Close shipments"
 NEW: Module BOM - Add tabs for nets Bom
 NEW: Module BOM - Add the possibility to add sub-BOMs to BOM
-NEW: Module Recruitment - Add a public page with all list of open job positions.
+NEW: Module Recruitment - Add a public page with list of all open job positions.
 NEW: Module Recruitment - Add a tab with list of application on the jobposition file.
-NEW: Module Website - supports now the multicompany module
 NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...)
 NEW: Add option to move checkbox column as first column on Thirdparty list (only few screens)
-NEW: on redirect of page in website module, GET parameters are kept.
-NEW: optional display warning icons on ticket list
 NEW: payment conditions enabling semi-automatic deposit creation (Issue #18439)
 NEW: possibility to consume multiple batch
 NEW: Reverse movement product consumption
 NEW: Send email to the supplier order contact
 NEW: add permission to report time on timesheet
-NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level
-NEW: Some core tables are created only at module activation
+NEW: Knowledge Management - Add status "Obsolete" to KM articles
 NEW: MRP - split consumption line on MO
+NEW: MRP - Display physical and virtual stock of the products when creating OF from a BOM
+NEW: MRP - Display product ref in "Object link" product tab for BOM
 NEW: Proposals - option update prices on proposal cloning
-NEW: stock filter in reassort lists
-NEW: stock limit in stock export CSV
+NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level
+NEW: Stocks - stock filter in reassort lists
+NEW: Stocks - stock limit in stock export CSV
 NEW: Supplier order - Show ref supplier of reception in linked object block
 NEW: support user_modif in order
 NEW: Surveys - Show number of votes into the label of tab "Results" of a survey
@@ -128,20 +122,24 @@ NEW: TakePOS - show product reference
 NEW: TakePOS - add constant to hide categories
 NEW: TakePOS - add constant to show category description
 NEW: TakePOS - add constant to show only the products in stock
+NEW: Third-Parties - Add rules "customer accountancy code" is mandatory to validate invoice
+NEW: Third-Parties - Can set the parent company during the creation of thirdparty (action=add of societe/card.php)
+NEW: Tickets - create Third-party with contact if not found on public ticket
 NEW: Tickets - option to default check "notify tier at creation"
 NEW: Tickets - Trigger: allow to automatically send messages on new tickets
+NEW: Tickets - optional display warning icons on ticket list
+NEW: Websites Module - supports now the multicompany module
+NEW: Websites Module - on redirect of page in website module, GET parameters are kept.
 NEW: The backup tools has an "lowmemory" option for mysqldump on large database
 NEW: The 'reposition' class works on ajax constantonoff that make redirects
-NEW: Thirdparty - Add rules "customer accountancy code" is mandatory to validate invoice
 NEW: thumbnail field in product list
 NEW: total mark rate in list
 NEW: uncheck "send message" by default on a ticket when private messages has been checked
 NEW: VAT Report by month - Show detail by rate and also by code
-NEW: Can store the session into database (instead of beeing managed by PHP)
 NEW: Added MMK currency (Myanmar Kyat)
 NEW: On a form to send an email, we show all emails of contacts of object
 
- Modules
+ Modules state
 NEW: Module Partnership Management
 NEW: Module Event Organization Management
 
@@ -164,7 +162,7 @@ NEW: Creation of the function select_bom() used to display bom select list
 NEW: Add trigger and event on completely received status change
 NEW: Add utility function send backup by mail
 NEW: add WordPress OAuth to save a token (not SSO)
-NEW: A module can embed a sql script run at each Dolibarr upgrade
+NEW: A module can embed a SQL script run at each Dolibarr upgrade
 NEW: Add param to keep the robot=index meta tag on public pages
 NEW: Add method hintindex() in database handlers.
 NEW: add modifications for new function "$db->prefix()"
@@ -209,9 +207,11 @@ NEW: TakePOS - add hook doaction in TakePOS invoice
 
 Config Options:
 NEW: Add hidden option on contract PDF line to hide qty and price
-NEW: Option INVOICEREC_SET_AUTOFILL_DATE_START/END
-NEW: Option MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND to send last document in mass mailing action
-
+NEW: Option  MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND  to send last document in mass mailing action
+NEW: Option  MAIN_API_DEBUG  to save API logs into a file
+NEW: Option  MAIN_MAIL_AUTOCOPY_TO  can accept several email and special keys
+NEW: Option  MAIN_SEARCH_CAT_OR_BY_DEFAULT  const for search by category
+NEW: Option  INVOICEREC_SET_AUTOFILL_DATE_START/END
 
 WARNING:
 

+ 1 - 1
htdocs/accountancy/journal/variousjournal.php

@@ -52,7 +52,7 @@ if ($result > 0) {
 } elseif ($result < 0) {
 	dol_print_error('', $object->error, $object->errors);
 } elseif ($result == 0) {
-	accessforbidden($langs->trans('ErrorRecordNotFound'));
+	accessforbidden('ErrorRecordNotFound');
 }
 
 $hookmanager->initHooks(array('globaljournal', $object->nature.'journal'));

+ 2 - 2
htdocs/adherents/canvas/default/tpl/adherentcard_view.tpl.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2010-2012 Regis Houssin  <regis.houssin@inodbox.com>
- * Copyright (C) 2012      Philippe Grand <philippe.grand@atoo-net.com>
+ * Copyright (C) 2012-2022 Philippe Grand <philippe.grand@atoo-net.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
@@ -124,7 +124,7 @@ if (!empty($this->control->tpl['action_delete'])) {
 if (empty($user->socid)) {
 	echo '<div class="tabsAction">';
 
-	if ($user->rights->adherent->creer) {
+	if ($user->hasRight('adherent', 'creer')) {
 		echo '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$this->control->tpl['id'].'&action=edit&token='.newToken().'&canvas='.$canvas.'">'.$langs->trans('Modify').'</a>';
 	}
 

+ 15 - 15
htdocs/adherents/card.php

@@ -110,10 +110,10 @@ if ($id > 0 || !empty($ref)) {
 }
 
 // Define variables to determine what the current user can do on the members
-$canaddmember = $user->rights->adherent->creer;
+$canaddmember = $user->hasRight('adherent', 'creer');
 // Define variables to determine what the current user can do on the properties of a member
 if ($id) {
-	$caneditfieldmember = $user->rights->adherent->creer;
+	$caneditfieldmember = $user->hasRight('adherent', 'creer');
 }
 
 // Security check
@@ -246,7 +246,7 @@ if (empty($reshook)) {
 		}
 	}
 
-	if ($action == 'update' && !$cancel && $user->rights->adherent->creer) {
+	if ($action == 'update' && !$cancel && $user->hasRight('adherent', 'creer')) {
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
 		$birthdate = '';
@@ -421,7 +421,7 @@ if (empty($reshook)) {
 		}
 	}
 
-	if ($action == 'add' && $user->rights->adherent->creer) {
+	if ($action == 'add' && $user->hasRight('adherent', 'creer')) {
 		if ($canvas) {
 			$object->canvas = $canvas;
 		}
@@ -629,7 +629,7 @@ if (empty($reshook)) {
 		}
 	}
 
-	if ($user->rights->adherent->creer && $action == 'confirm_valid' && $confirm == 'yes') {
+	if ($user->hasRight('adherent', 'creer') && $action == 'confirm_valid' && $confirm == 'yes') {
 		$error = 0;
 
 		$db->begin();
@@ -854,7 +854,7 @@ if (empty($reshook)) {
 		}
 	}
 
-	if ($user->rights->adherent->creer && $action == 'confirm_add_spip' && $confirm == 'yes') {
+	if ($user->hasRight('adherent', 'creer') && $action == 'confirm_add_spip' && $confirm == 'yes') {
 		if (!count($object->errors)) {
 			if (!$mailmanspip->add_to_spip($object)) {
 				setEventMessages($langs->trans('AddIntoSpipError').': '.$mailmanspip->error, null, 'errors');
@@ -867,7 +867,7 @@ if (empty($reshook)) {
 
 	// Actions to build doc
 	$upload_dir = $conf->adherent->dir_output;
-	$permissiontoadd = $user->rights->adherent->creer;
+	$permissiontoadd = $user->hasRight('adherent', 'creer');
 	include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
 
 	// Actions to send emails
@@ -1222,7 +1222,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 
 		// Type
 		print '<tr><td class="fieldrequired">'.$langs->trans("Type").'</td><td>';
-		if ($user->rights->adherent->creer) {
+		if ($user->hasRight('adherent', 'creer')) {
 			print $form->selectarray("typeid", $adht->liste_array(), (GETPOSTISSET("typeid") ? GETPOST("typeid", 'int') : $object->typeid), 0, 0, 0, '', 0, 0, 0, '', '', 1);
 		} else {
 			print $adht->getNomUrl(1);
@@ -1820,7 +1820,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 		// Third party Dolibarr
 		if (isModEnabled('societe')) {
 			print '<tr><td>';
-			$editenable = $user->rights->adherent->creer;
+			$editenable = $user->hasRight('adherent', 'creer');
 			print $form->editfieldkey('LinkedToDolibarrThirdParty', 'thirdparty', '', $object, $editenable);
 			print '</td><td colspan="2" class="valeur">';
 			if ($action == 'editthirdparty') {
@@ -1857,7 +1857,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 
 		// Login Dolibarr - Link to user
 		print '<tr><td>';
-		$editenable = $user->rights->adherent->creer && $user->rights->user->user->creer;
+		$editenable = $user->hasRight('adherent', 'creer') && $user->rights->user->user->creer;
 		print $form->editfieldkey('LinkedToDolibarrUser', 'login', '', $object, $editenable);
 		print '</td><td colspan="2" class="valeur">';
 		if ($action == 'editlogin') {
@@ -1901,7 +1901,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 				// Send card by email
 				// TODO Remove this to replace with a template
 				/*
-				if ($user->rights->adherent->creer) {
+				if ($user->hasRight('adherent', 'creer')) {
 					if (Adherent::STATUS_VALIDATED == $object->statut) {
 						if ($object->email) print '<a class="butAction" href="card.php?rowid='.$object->id.'&action=sendinfo">'.$langs->trans("SendCardByMail")."</a>\n";
 						else print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NoEMail")).'">'.$langs->trans("SendCardByMail")."</a>\n";
@@ -1913,7 +1913,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 				}*/
 
 				// Modify
-				if (!empty($user->rights->adherent->creer)) {
+				if ($user->hasRight('adherent', 'creer')) {
 					print '<a class="butAction" href="card.php?rowid='.$id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>'."\n";
 				} else {
 					print '<span class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("Modify").'</span>'."\n";
@@ -1921,7 +1921,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 
 				// Validate
 				if (Adherent::STATUS_DRAFT == $object->statut) {
-					if ($user->rights->adherent->creer) {
+					if ($user->hasRight('adherent', 'creer')) {
 						print '<a class="butAction" href="card.php?rowid='.$id.'&action=valid">'.$langs->trans("Validate").'</a>'."\n";
 					} else {
 						print '<span class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("Validate").'</span>'."\n";
@@ -1930,7 +1930,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 
 				// Reactivate
 				if (Adherent::STATUS_RESILIATED == $object->statut || Adherent::STATUS_EXCLUDED == $object->statut) {
-					if ($user->rights->adherent->creer) {
+					if ($user->hasRight('adherent', 'creer')) {
 						print '<a class="butAction" href="card.php?rowid='.$id.'&action=valid">'.$langs->trans("Reenable")."</a>\n";
 					} else {
 						print '<span class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("Reenable").'</span>'."\n";
@@ -2022,7 +2022,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 			$filedir = $conf->adherent->dir_output.'/'.get_exdir(0, 0, 0, 1, $object, 'member');
 			$urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
 			$genallowed = $user->rights->adherent->lire;
-			$delallowed = $user->rights->adherent->creer;
+			$delallowed = $user->hasRight('adherent', 'creer');
 
 			print $formfile->showdocuments('member', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', (empty($object->default_lang) ? '' : $object->default_lang), '', $object);
 			$somethingshown = $formfile->numoffiles;

+ 3 - 3
htdocs/adherents/class/api_members.class.php

@@ -2,7 +2,7 @@
 /* Copyright (C) 2016	Xebax Christy	<xebax@wanadoo.fr>
  * Copyright (C) 2017	Regis Houssin	<regis.houssin@inodbox.com>
  * Copyright (C) 2020	Thibault FOUCART<support@ptibogxiv.net>
- * Copyright (C) 2020		Frédéric France		<frederic.france@netlogic.fr>
+ * Copyright (C) 2020	Frédéric France	<frederic.france@netlogic.fr>
  *
  * 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
@@ -286,7 +286,7 @@ class Members extends DolibarrApi
 	 */
 	public function post($request_data = null)
 	{
-		if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+		if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 			throw new RestException(401);
 		}
 		// Check mandatory fields
@@ -311,7 +311,7 @@ class Members extends DolibarrApi
 	 */
 	public function put($id, $request_data = null)
 	{
-		if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+		if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 			throw new RestException(401);
 		}
 

+ 1 - 1
htdocs/adherents/class/api_subscriptions.class.php

@@ -173,7 +173,7 @@ class Subscriptions extends DolibarrApi
 	 */
 	public function put($id, $request_data = null)
 	{
-		if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+		if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 			throw new RestException(401);
 		}
 

+ 4 - 4
htdocs/adherents/document.php

@@ -88,10 +88,10 @@ if ($id > 0 || !empty($ref)) {
 }
 
 // Define variables to determine what the current user can do on the members
-$canaddmember = $user->rights->adherent->creer;
+$canaddmember = $user->hasRight('adherent', 'creer');
 // Define variables to determine what the current user can do on the properties of a member
 if ($id) {
-	$caneditfieldmember = $user->rights->adherent->creer;
+	$caneditfieldmember = $user->hasRight('adherent', 'creer');
 }
 
 $permissiontoadd = $canaddmember;
@@ -187,8 +187,8 @@ if ($id > 0) {
 		print dol_get_fiche_end();
 
 		$modulepart = 'member';
-		$permissiontoadd = $user->rights->adherent->creer;
-		$permtoedit = $user->rights->adherent->creer;
+		$permissiontoadd = $user->hasRight('adherent', 'creer');
+		$permtoedit = $user->hasRight('adherent', 'creer');
 		$param = '&id='.$object->id;
 		include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php';
 		print "<br><br>";

+ 2 - 2
htdocs/adherents/ldap.php

@@ -63,10 +63,10 @@ if ($id > 0 || !empty($ref)) {
 }
 
 // Define variables to determine what the current user can do on the members
-$canaddmember = $user->rights->adherent->creer;
+$canaddmember = $user->hasRight('adherent', 'creer');
 // Define variables to determine what the current user can do on the properties of a member
 if ($id) {
-	$caneditfieldmember = $user->rights->adherent->creer;
+	$caneditfieldmember = $user->hasRight('adherent', 'creer');
 }
 
 // Security check

+ 6 - 6
htdocs/adherents/list.php

@@ -232,7 +232,7 @@ if (empty($reshook)) {
 	}
 
 	// Close
-	if ($massaction == 'close' && $user->rights->adherent->creer) {
+	if ($massaction == 'close' && $user->hasRight('adherent', 'creer')) {
 		$tmpmember = new Adherent($db);
 		$error = 0;
 		$nbclose = 0;
@@ -262,7 +262,7 @@ if (empty($reshook)) {
 	}
 
 	// Create external user
-	if ($massaction == 'createexternaluser' && $user->rights->adherent->creer && $user->rights->user->user->creer) {
+	if ($massaction == 'createexternaluser' && $user->hasRight('adherent', 'creer') && $user->rights->user->user->creer) {
 		$tmpmember = new Adherent($db);
 		$error = 0;
 		$nbcreated = 0;
@@ -302,7 +302,7 @@ if (empty($reshook)) {
 	$objectlabel = 'Members';
 	$permissiontoread = $user->rights->adherent->lire;
 	$permissiontodelete = $user->rights->adherent->supprimer;
-	$permissiontoadd = $user->rights->adherent->creer;
+	$permissiontoadd = $user->hasRight('adherent', 'creer');
 	$uploaddir = $conf->adherent->dir_output;
 	include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
 }
@@ -617,7 +617,7 @@ $arrayofmassactions = array(
 	//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
 	//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
 );
-if ($user->rights->adherent->creer) {
+if ($user->hasRight('adherent', 'creer')) {
 	$arrayofmassactions['close'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Resiliate");
 }
 if ($user->rights->adherent->supprimer) {
@@ -626,7 +626,7 @@ if ($user->rights->adherent->supprimer) {
 if ($user->rights->societe->creer) {
 	$arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
 }
-if ($user->rights->adherent->creer && $user->rights->user->user->creer) {
+if ($user->hasRight('adherent', 'creer') && $user->rights->user->user->creer) {
 	$arrayofmassactions['createexternaluser'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("CreateExternalUser");
 }
 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) {
@@ -635,7 +635,7 @@ if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'pr
 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
 
 $newcardbutton = '';
-if ($user->rights->adherent->creer) {
+if ($user->hasRight('adherent', 'creer')) {
 	$newcardbutton .= dolGetButtonTitle($langs->trans('NewMember'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/card.php?action=create');
 }
 

+ 4 - 4
htdocs/adherents/note.php

@@ -51,7 +51,7 @@ if ($result > 0) {
 }
 
 
-$permissionnote = $user->rights->adherent->creer; // Used by the include of actions_setnotes.inc.php
+$permissionnote = $user->hasRight('adherent', 'creer'); // Used by the include of actions_setnotes.inc.php
 
 // Fetch object
 if ($id > 0 || !empty($ref)) {
@@ -71,10 +71,10 @@ if ($id > 0 || !empty($ref)) {
 }
 
 // Define variables to determine what the current user can do on the members
-$canaddmember = $user->rights->adherent->creer;
+$canaddmember = $user->hasRight('adherent', 'creer');
 // Define variables to determine what the current user can do on the properties of a member
 if ($id) {
-	$caneditfieldmember = $user->rights->adherent->creer;
+	$caneditfieldmember = $user->hasRight('adherent', 'creer');
 }
 
 $hookmanager->initHooks(array('membernote'));
@@ -155,7 +155,7 @@ if ($id) {
 
 
 	$cssclass = 'titlefield';
-	$permission = $user->rights->adherent->creer; // Used by the include of notes.tpl.php
+	$permission = $user->hasRight('adherent', 'creer'); // Used by the include of notes.tpl.php
 	include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php';
 
 

+ 4 - 4
htdocs/adherents/subscription.php

@@ -113,10 +113,10 @@ if ($id > 0 || !empty($ref)) {
 }
 
 // Define variables to determine what the current user can do on the members
-$canaddmember = $user->rights->adherent->creer;
+$canaddmember = $user->hasRight('adherent', 'creer');
 // Define variables to determine what the current user can do on the properties of a member
 if ($id) {
-	$caneditfieldmember = $user->rights->adherent->creer;
+	$caneditfieldmember = $user->hasRight('adherent', 'creer');
 }
 
 // Security check
@@ -595,7 +595,7 @@ if ($rowid > 0) {
 		print '<table class="nobordernopadding" width="100%"><tr><td>';
 		print $langs->trans("LinkedToDolibarrThirdParty");
 		print '</td>';
-		if ($action != 'editthirdparty' && $user->rights->adherent->creer) {
+		if ($action != 'editthirdparty' && $user->hasRight('adherent', 'creer')) {
 			print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editthirdparty&token='.newToken().'&rowid='.$object->id.'">'.img_edit($langs->trans('SetLinkToThirdParty'), 1).'</a></td>';
 		}
 		print '</tr></table>';
@@ -637,7 +637,7 @@ if ($rowid > 0) {
 	print '<table class="nobordernopadding" width="100%"><tr><td>';
 	print $langs->trans("LinkedToDolibarrUser");
 	print '</td>';
-	if ($action != 'editlogin' && $user->rights->adherent->creer) {
+	if ($action != 'editlogin' && $user->hasRight('adherent', 'creer')) {
 		print '<td class="right">';
 		if ($user->rights->user->user->creer) {
 			print '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editlogin&token='.newToken().'&rowid='.$object->id.'">'.img_edit($langs->trans('SetLinkToUser'), 1).'</a>';

+ 1 - 1
htdocs/adherents/type.php

@@ -754,7 +754,7 @@ if ($rowid > 0) {
 
 				// Actions
 				print '<td class="center">';
-				if ($user->rights->adherent->creer) {
+				if ($user->hasRight('adherent', 'creer')) {
 					print '<a class="editfielda marginleftonly" href="card.php?rowid='.$objp->rowid.'&action=edit&token='.newToken().'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?rowid='.$object->id).'">'.img_edit().'</a>';
 				}
 				if ($user->rights->adherent->supprimer) {

+ 2 - 2
htdocs/adherents/vcard.php

@@ -54,10 +54,10 @@ if ($id > 0 || !empty($ref)) {
 }
 
 // Define variables to determine what the current user can do on the members
-$canaddmember = $user->rights->adherent->creer;
+$canaddmember = $user->hasRight('adherent', 'creer');
 // Define variables to determine what the current user can do on the properties of a member
 if ($id) {
-	$caneditfieldmember = $user->rights->adherent->creer;
+	$caneditfieldmember = $user->hasRight('adherent', 'creer');
 }
 
 // Security check

+ 2 - 2
htdocs/admin/clicktodial.php

@@ -36,8 +36,8 @@ if (!$user->admin) {
 
 $action = GETPOST('action', 'aZ09');
 
-if (!in_array('clicktodial', $conf->modules)) {
-	accessforbidden($langs->trans("WarningModuleNotActive", $langs->transnoentitiesnoconv("Module58Name")));
+if (!isModEnabled('clicktodial')) {
+	accessforbidden($langs->transnoentitiesnoconv("WarningModuleNotActive", $langs->transnoentitiesnoconv("Module58Name")));
 }
 
 

+ 4 - 4
htdocs/admin/fichinter.php

@@ -538,7 +538,7 @@ print '<input type="hidden" name="action" value="set_FICHINTER_PRINT_PRODUCTS">'
 print '<tr class="oddeven"><td>';
 print $langs->trans("PrintProductsOnFichinter").' ('.$langs->trans("PrintProductsOnFichinterDetails").')</td>';
 print '<td align="center"><input type="checkbox" name="FICHINTER_PRINT_PRODUCTS" ';
-if ($conf->global->FICHINTER_PRINT_PRODUCTS) {
+if (getDolGlobalString("FICHINTER_PRINT_PRODUCTS")) {
 	print 'checked ';
 }
 print '/>';
@@ -555,7 +555,7 @@ print '<td>';
 print $langs->trans("UseServicesDurationOnFichinter");
 print '</td>';
 print '<td class="center">';
-print '<input type="checkbox" name="FICHINTER_USE_SERVICE_DURATION"'.($conf->global->FICHINTER_USE_SERVICE_DURATION ? ' checked' : '').'>';
+print '<input type="checkbox" name="FICHINTER_USE_SERVICE_DURATION"'.(getDolGlobalString("FICHINTER_USE_SERVICE_DURATION") ? ' checked' : '').'>';
 print '</td>';
 print '<td class="right">';
 print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'">';
@@ -571,7 +571,7 @@ print '<td>';
 print $langs->trans("UseDurationOnFichinter");
 print '</td>';
 print '<td class="center">';
-print '<input type="checkbox" name="FICHINTER_WITHOUT_DURATION"'.($conf->global->FICHINTER_WITHOUT_DURATION ? ' checked' : '').'>';
+print '<input type="checkbox" name="FICHINTER_WITHOUT_DURATION"'.(getDolGlobalString("FICHINTER_WITHOUT_DURATION") ? ' checked' : '').'>';
 print '</td>';
 print '<td class="right">';
 print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'">';
@@ -587,7 +587,7 @@ print '<td>';
 print $langs->trans("UseDateWithoutHourOnFichinter");
 print '</td>';
 print '<td class="center">';
-print '<input type="checkbox" name="FICHINTER_DATE_WITHOUT_HOUR"'.($conf->global->FICHINTER_DATE_WITHOUT_HOUR ? ' checked' : '').'>';
+print '<input type="checkbox" name="FICHINTER_DATE_WITHOUT_HOUR"'.(getDolGlobalString("FICHINTER_DATE_WITHOUT_HOUR") ? ' checked' : '').'>';
 print '</td>';
 print '<td class="right">';
 print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'">';

+ 1 - 1
htdocs/admin/hrm.php

@@ -624,7 +624,7 @@ if ($action == 'edit') {
 						setEventMessages(null, $object->errors, "errors");
 					}
 				} else {
-					print $conf->global->{$constname};
+					print getDolGlobalString($constname);
 				}
 				print '</td></tr>';
 			}

+ 3 - 3
htdocs/admin/reception_setup.php

@@ -238,7 +238,7 @@ foreach ($dirmodels as $reldir) {
 						if ($conf->global->RECEPTION_ADDON_NUMBER == "$file") {
 							print img_picto($langs->trans("Activated"), 'switch_on');
 						} else {
-							print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setmodel&token='.newToken().'&value='.urlencode($file).'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'">';
+							print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setmodel&token='.newToken().'&value='.urlencode($file).(!empty($module->scandir) ? '&scan_dir='.$module->scandir : '').(!empty($module->name) ? '&label='.urlencode($module->name) : '').'">';
 							print img_picto($langs->trans("Disabled"), 'switch_off');
 							print '</a>';
 						}
@@ -345,10 +345,10 @@ foreach ($dirmodels as $reldir) {
 							$module = new $classname($db);
 
 							$modulequalified = 1;
-							if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
+							if (isset($module->version) && $module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
 								$modulequalified = 0;
 							}
-							if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
+							if (isset($module->version) && $module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
 								$modulequalified = 0;
 							}
 

+ 1 - 1
htdocs/admin/supplier_invoice.php

@@ -393,7 +393,7 @@ foreach ($dirmodels as $reldir) {
 
 					// Default
 					print '<td class="center">';
-					if ($conf->global->INVOICE_SUPPLIER_ADDON_PDF == "$name") {
+					if (getDolGlobalString("INVOICE_SUPPLIER_ADDON_PDF") == "$name") {
 						//print img_picto($langs->trans("Default"),'on');
 						// Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all
 						print '<a href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';

+ 55 - 53
htdocs/admin/supplier_order.php

@@ -1,25 +1,25 @@
 <?php
 /* Copyright (C) 2003-2007 Rodolphe Quiedeville    <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2011 Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2011 Regis Houssin           <regis.houssin@inodbox.com>
- * Copyright (C) 2004      Sebastien Di Cintio     <sdicintio@ressource-toi.org>
- * Copyright (C) 2004      Benoit Mortier          <benoit.mortier@opensides.be>
- * Copyright (C) 2010-2013 Juanjo Menent           <jmenent@2byte.es>
- * Copyright (C) 2011-2018 Philippe Grand          <philippe.grand@atoo-net.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
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
+* Copyright (C) 2004-2011 Laurent Destailleur     <eldy@users.sourceforge.net>
+* Copyright (C) 2005-2011 Regis Houssin           <regis.houssin@inodbox.com>
+* Copyright (C) 2004      Sebastien Di Cintio     <sdicintio@ressource-toi.org>
+* Copyright (C) 2004      Benoit Mortier          <benoit.mortier@opensides.be>
+* Copyright (C) 2010-2013 Juanjo Menent           <jmenent@2byte.es>
+* Copyright (C) 2011-2018 Philippe Grand          <philippe.grand@atoo-net.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
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
 
 /**
  *  \file       htdocs/admin/supplier_order.php
@@ -55,8 +55,8 @@ $specimenthirdparty->initAsSpecimen();
 
 
 /*
- * Actions
- */
+* Actions
+*/
 
 include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
 
@@ -85,7 +85,9 @@ if ($action == 'updateMask') {
 	$commande->thirdparty = $specimenthirdparty;
 
 	// Search template files
-	$file = ''; $classname = ''; $filefound = 0;
+	$file = '';
+	$classname = '';
+	$filefound = 0;
 	$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
 	foreach ($dirmodels as $reldir) {
 		$file = dol_buildpath($reldir."core/modules/supplier_order/doc/pdf_".$modele.".modules.php", 0);
@@ -195,8 +197,8 @@ if ($action == 'updateMask') {
 
 
 /*
- * View
- */
+* View
+*/
 
 $form = new Form($db);
 
@@ -314,8 +316,8 @@ print '</table><br>';
 
 
 /*
- *  Documents models for supplier orders
- */
+*  Documents models for supplier orders
+*/
 
 print load_fiche_titre($langs->trans("OrdersModelModule"), '', '');
 
@@ -370,7 +372,7 @@ foreach ($dirmodels as $reldir) {
 
 					print "<tr class=\"oddeven\">\n";
 					print "<td>";
-					print (empty($module->name) ? $name : $module->name);
+					print(empty($module->name) ? $name : $module->name);
 					print "</td>\n";
 					print "<td>\n";
 					require_once $dir.'/'.$file;
@@ -438,8 +440,8 @@ foreach ($dirmodels as $reldir) {
 print '</table><br>';
 
 /*
- * Other options
- */
+* Other options
+*/
 
 print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
 print '<input type="hidden" name="token" value="'.newToken().'">';
@@ -457,7 +459,7 @@ print '<tr class="oddeven"><td>';
 print $form->textwithpicto($langs->trans("UseDoubleApproval"), $langs->trans("Use3StepsApproval"), 1, 'help').'<br>';
 print $langs->trans("IfSetToYesDontForgetPermission");
 print '</td><td>';
-print '<input type="text" size="6" name="SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED" value="'.$conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED.'">';
+print '<input type="text" size="6" name="SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED" value="'.getDolGlobalString("SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED").'">';
 print '</td><td class="right">';
 print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'">';
 print "</td></tr>\n";
@@ -467,30 +469,30 @@ print "</td></tr>\n";
 /* Kept as hidden for the moment
 if (isModEnabled('banque')) {
 
-	print '<tr class="oddeven"><td>';
-	print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER").'</td><td>&nbsp;</td><td align="center">';
-	if (!empty($conf->use_javascript_ajax))
-	{
-		print ajax_constantonoff('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER');
-	}
-	else
-	{
-		if (empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER))
-		{
-			print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER&token='.newToken().'&value=1">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
-		}
-		else
-		{
-			print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER&token='.newToken().'&value=0">'.img_picto($langs->trans("Enabled"),'switch_on').'</a>';
-		}
-	}
-	print '</td></tr>';
+print '<tr class="oddeven"><td>';
+print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER").'</td><td>&nbsp;</td><td align="center">';
+if (!empty($conf->use_javascript_ajax))
+{
+print ajax_constantonoff('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER');
+}
+else
+{
+if (empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER))
+{
+print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER&token='.newToken().'&value=1">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
+}
+else
+{
+print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER&token='.newToken().'&value=0">'.img_picto($langs->trans("Enabled"),'switch_on').'</a>';
+}
+}
+print '</td></tr>';
 }
 else
 {
 
-	print '<tr class="oddeven"><td>';
-	print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER").'</td><td>&nbsp;</td><td align="center">'.$langs->trans('NotAvailable').'</td></tr>';
+print '<tr class="oddeven"><td>';
+print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER").'</td><td>&nbsp;</td><td align="center">'.$langs->trans('NotAvailable').'</td></tr>';
 }
 */
 
@@ -540,8 +542,8 @@ print '</form>';
 
 
 /*
- * Notifications
- */
+* Notifications
+*/
 
 print load_fiche_titre($langs->trans("Notifications"), '', '');
 print '<table class="noborder centpercent">';

+ 6 - 6
htdocs/admin/supplier_payment.php

@@ -75,7 +75,7 @@ if ($action == 'updateMask') {
 } elseif ($action == 'del') {
 	$ret = delDocumentModel($value, $type);
 	if ($ret > 0) {
-		if ($conf->global->FACTURE_ADDON_PDF == "$value") {
+		if (getDolGlobalString("FACTURE_ADDON_PDF") == "$value") {
 			dolibarr_del_const($db, 'SUPPLIER_PAYMENT_ADDON_PDF', $conf->entity);
 		}
 	}
@@ -263,7 +263,7 @@ foreach ($dirmodels as $reldir) {
 							if ($conf->global->SUPPLIER_PAYMENT_ADDON == $file || $conf->global->SUPPLIER_PAYMENT_ADDON.'.php' == $file) {
 								print img_picto($langs->trans("Activated"), 'switch_on');
 							} else {
-								print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&value='.preg_replace('/\.php$/', '', $file).'&scandir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
+								print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&value='.preg_replace('/\.php$/', '', $file).(!empty($module->scandir) ? '&scandir='.$module->scandir : '').'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
 							}
 							print '</td>';
 
@@ -289,7 +289,7 @@ foreach ($dirmodels as $reldir) {
 							print '<td class="center">';
 							print $form->textwithpicto('', $htmltooltip, 1, 0);
 
-							if ($conf->global->PAYMENT_ADDON.'.php' == $file) {  // If module is the one used, we show existing errors
+							if (getDolGlobalString("PAYMENT_ADDON").'.php' == $file) {  // If module is the one used, we show existing errors
 								if (!empty($module->error)) {
 									dol_htmloutput_mesg($module->error, '', 'error', 1);
 								}
@@ -351,7 +351,7 @@ foreach ($dirmodels as $reldir) {
 					print "</td>\n";
 					print "<td>\n";
 					require_once $dir.'/'.$file;
-					$module = new $classname($db, $specimenthirdparty);
+					$module = new $classname($db, new Societe($db));
 					if (method_exists($module, 'info')) {
 						print $module->info($langs);
 					} else {
@@ -383,7 +383,7 @@ foreach ($dirmodels as $reldir) {
 
 					// Default
 					print '<td class="center">';
-					if ($conf->global->SUPPLIER_PAYMENT_ADDON_PDF == "$name") {
+					if (getDolGlobalString("SUPPLIER_PAYMENT_ADDON_PDF") == "$name") {
 						//print img_picto($langs->trans("Default"),'on');
 						// Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all
 						print '<a href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&token='.newToken().'&value='.urlencode($name).'&scandir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&type=SUPPLIER_PAYMENT"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
@@ -442,7 +442,7 @@ print "</tr>\n";
 print '<tr class="oddeven"><td>';
 print $langs->trans("GroupPaymentsByModOnReports");
 print '</td><td width="60" align="center">';
-print $form->selectyesno("PAYMENTS_FOURN_REPORT_GROUP_BY_MOD", $conf->global->PAYMENTS_FOURN_REPORT_GROUP_BY_MOD, 1);
+print $form->selectyesno("PAYMENTS_FOURN_REPORT_GROUP_BY_MOD", getDolGlobalString("PAYMENTS_FOURN_REPORT_GROUP_BY_MOD"), 1);
 print '</td><td class="right">';
 print "</td></tr>\n";
 

+ 3 - 2
htdocs/admin/ticket.php

@@ -429,7 +429,7 @@ foreach ($dirmodels as $reldir) {
 
 								// Default
 								print '<td class="center">';
-								if ($conf->global->TICKET_ADDON_PDF == $name) {
+								if (getDolGlobalString("TICKET_ADDON_PDF") == $name) {
 									print img_picto($langs->trans("Default"), 'on');
 								} else {
 									print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setdoc&amp;token='.newToken().'&amp;value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
@@ -541,9 +541,10 @@ print '</td>';
 print '</tr>';
 
 if (isModEnabled('product')) {
+	$htmlname = "product_category_id";
 	print '<tr class="oddeven"><td>'.$langs->trans("TicketChooseProductCategory").'</td>';
 	print '<td class="left">';
-	$formcategory->selectProductCategory($conf->global->TICKET_PRODUCT_CATEGORY, 'product_category_id');
+	$formcategory->selectProductCategory($conf->global->TICKET_PRODUCT_CATEGORY, $htmlname);
 	if ($conf->use_javascript_ajax) {
 		print ajax_combobox('select_'.$htmlname);
 	}

+ 8 - 8
htdocs/admin/ticket_public.php

@@ -382,10 +382,10 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
 	}
 
 	// Interface topic
-	$url_interface = $conf->global->TICKET_PUBLIC_INTERFACE_TOPIC;
+	$url_interface = getDolGlobalString("TICKET_PUBLIC_INTERFACE_TOPIC");
 	print '<tr><td>'.$langs->trans("TicketPublicInterfaceTopicLabelAdmin").'</label>';
 	print '</td><td>';
-	print '<input type="text"   name="TICKET_PUBLIC_INTERFACE_TOPIC" value="'.$conf->global->TICKET_PUBLIC_INTERFACE_TOPIC.'" size="40" ></td>';
+	print '<input type="text"   name="TICKET_PUBLIC_INTERFACE_TOPIC" value="'.$url_interface.'" size="40" ></td>';
 	print '</td>';
 	print '<td class="center width75">';
 	print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTopicHelp"), 1, 'help');
@@ -404,7 +404,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
 	print '</td></tr>';
 
 	// Text to help to enter a ticket
-	$public_text_help_message = $conf->global->TICKET_PUBLIC_TEXT_HELP_MESSAGE ? $conf->global->TICKET_PUBLIC_TEXT_HELP_MESSAGE : $langs->trans('TicketPublicPleaseBeAccuratelyDescribe');
+	$public_text_help_message = getDolGlobalString("TICKET_PUBLIC_TEXT_HELP_MESSAGE", $langs->trans('TicketPublicPleaseBeAccuratelyDescribe'));
 	print '<tr><td>'.$langs->trans("TicketPublicInterfaceTextHelpMessageLabelAdmin").'</label>';
 	print '</td><td>';
 	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
@@ -416,10 +416,10 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
 	print '</td></tr>';
 
 	// Url public interface
-	$url_interface = $conf->global->TICKET_URL_PUBLIC_INTERFACE;
+	$url_interface = getDolGlobalString("TICKET_URL_PUBLIC_INTERFACE");
 	print '<tr><td>'.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").'</label>';
 	print '</td><td>';
-	print '<input type="text" class="minwidth500" name="TICKET_URL_PUBLIC_INTERFACE" value="'.$conf->global->TICKET_URL_PUBLIC_INTERFACE.'"></td>';
+	print '<input type="text" class="minwidth500" name="TICKET_URL_PUBLIC_INTERFACE" value="'.$url_interface.'"></td>';
 	print '</td>';
 	print '<td class="center">';
 	print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help');
@@ -449,7 +449,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
 	print '</tr>';
 
 	// Text of email after creatio of a ticket
-	$mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody');
+	$mail_mesg_new = getDolGlobalString("TICKET_MESSAGE_MAIL_NEW", $langs->trans('TicketNewEmailBody'));
 	print '<tr><td>';
 	print $form->textwithpicto($langs->trans("TicketNewEmailBodyLabel"), $langs->trans("TicketNewEmailBodyHelp"), 1, 'help');
 	print '</label>';
@@ -469,7 +469,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
 		print ajax_constantonoff('TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED');
 	} else {
 		$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-		print $form->selectarray("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED", $arrval, $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED);
+		print $form->selectarray("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED", $arrval, getDolGlobalString("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED"));
 	}
 	print '</td>';
 	print '</tr>';
@@ -478,7 +478,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
 	print '<tr><td>';
 	print $form->textwithpicto($langs->trans("TicketPublicNotificationNewMessageDefaultEmail"), $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help');
 	print '</td><td>';
-	print '<input type="text" name="TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL" value="'.$conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL.'" size="40" ></td>';
+	print '<input type="text" name="TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL" value="'.getDolGlobalString("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL").'" size="40" ></td>';
 	print '</td>';
 	print '</tr>';
 

+ 10 - 5
htdocs/admin/tools/purge.php

@@ -34,7 +34,7 @@ $langs->load("admin");
 $action = GETPOST('action', 'aZ09');
 $confirm = GETPOST('confirm', 'alpha');
 $choice = GETPOST('choice', 'aZ09');
-
+$nbsecondsold = GETPOSTINT('nbsecondsold');
 
 // Define filelog to discard it from purge
 $filelog = '';
@@ -43,6 +43,7 @@ if (!empty($conf->syslog->enabled)) {
 	$filelog = preg_replace('/DOL_DATA_ROOT/i', DOL_DATA_ROOT, $filelog);
 }
 
+// Security
 if (!$user->admin) {
 	accessforbidden();
 }
@@ -65,7 +66,8 @@ if ($action == 'purge' && !preg_match('/^confirm/i', $choice) && ($choice != 'al
 
 	require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
 	$utils = new Utils($db);
-	$result = $utils->purgeFiles($choice);
+
+	$result = $utils->purgeFiles($choice, $nbsecondsold);
 
 	$mesg = $utils->output;
 	setEventMessages($mesg, null, 'mesgs');
@@ -115,8 +117,11 @@ print '> <label for="choicetempfiles">'.$langs->trans("PurgeDeleteTemporaryFiles
 
 print '<input type="radio" name="choice" id="choiceallfiles" value="confirm_allfiles"';
 print ($choice && $choice == 'confirm_allfiles') ? ' checked' : '';
-print '> <label for="choiceallfiles">'.$langs->trans("PurgeDeleteAllFilesInDocumentsDir", $dolibarr_main_data_root).'</label><br>';
-
+print '> <label for="choiceallfiles">'.$langs->trans("PurgeDeleteAllFilesInDocumentsDir", $dolibarr_main_data_root).'</label>';
+print '<br>';
+if (getDolGlobalInt('MAIN_PURGE_ACCEPT_NBSECONDSOLD')) {
+	print 'NbSecondsOld = <input class="width50 right" type="text" name="nbsecondsold" value="'.$nbsecondsold.'">';
+}
 print '</td></tr></table>';
 
 //if ($choice != 'confirm_allfiles')
@@ -130,7 +135,7 @@ print '</form>';
 if (preg_match('/^confirm/i', $choice)) {
 	print '<br>';
 	$formquestion = array();
-	print $form->formconfirm($_SERVER["PHP_SELF"].'?choice=allfiles', $langs->trans('Purge'), $langs->trans('ConfirmPurge').img_warning().' ', 'purge', $formquestion, 'no', 2);
+	print $form->formconfirm($_SERVER["PHP_SELF"].'?choice=allfiles&nbsecondsold='.$nbsecondsold, $langs->trans('Purge'), $langs->trans('ConfirmPurge').img_warning().' ', 'purge', $formquestion, 'no', 2);
 }
 
 // End of page

+ 2 - 0
htdocs/api/index.php

@@ -76,6 +76,8 @@ if (preg_match('/\/api\/index\.php/', $_SERVER["PHP_SELF"])) {
 	header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
 	header('Access-Control-Allow-Headers: Content-Type, Authorization, api_key, DOLAPIKEY');
 }
+header('X-Frame-Options: SAMEORIGIN');
+
 
 $res = 0;
 if (!$res && file_exists("../main.inc.php")) {

+ 4 - 4
htdocs/categories/class/api_categories.class.php

@@ -386,7 +386,7 @@ class Categories extends DolibarrApi
 			}
 			$object = new Contact($this->db);
 		} elseif ($type === Categorie::TYPE_MEMBER) {
-			if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+			if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 				throw new RestException(401);
 			}
 			$object = new Adherent($this->db);
@@ -466,7 +466,7 @@ class Categories extends DolibarrApi
 			}
 			$object = new Contact($this->db);
 		} elseif ($type === Categorie::TYPE_MEMBER) {
-			if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+			if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 				throw new RestException(401);
 			}
 			$object = new Adherent($this->db);
@@ -546,7 +546,7 @@ class Categories extends DolibarrApi
 			}
 			$object = new Contact($this->db);
 		} elseif ($type === Categorie::TYPE_MEMBER) {
-			if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+			if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 				throw new RestException(401);
 			}
 			$object = new Adherent($this->db);
@@ -624,7 +624,7 @@ class Categories extends DolibarrApi
 			}
 			$object = new Contact($this->db);
 		} elseif ($type === Categorie::TYPE_MEMBER) {
-			if (!DolibarrApiAccess::$user->rights->adherent->creer) {
+			if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
 				throw new RestException(401);
 			}
 			$object = new Adherent($this->db);

+ 13 - 13
htdocs/categories/viewcat.php

@@ -118,7 +118,7 @@ if ($id > 0 && $removeelem > 0 && $action == 'unlink') {
 		$tmpobject = new Societe($db);
 		$result = $tmpobject->fetch($removeelem);
 		$elementtype = 'customer';
-	} elseif ($type == Categorie::TYPE_MEMBER && $user->rights->adherent->creer) {
+	} elseif ($type == Categorie::TYPE_MEMBER && $user->hasRight('adherent', 'creer')) {
 		require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
 		$tmpobject = new Adherent($db);
 		$result = $tmpobject->fetch($removeelem);
@@ -564,7 +564,7 @@ if ($type == Categorie::TYPE_PRODUCT) {
 		}
 	} else {
 		print_barre_liste($langs->trans("ProductsAndServices"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'products');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -644,7 +644,7 @@ if ($type == Categorie::TYPE_CUSTOMER) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Customers"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'companies');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -725,7 +725,7 @@ if ($type == Categorie::TYPE_SUPPLIER) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Suppliers"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'companies');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -734,7 +734,7 @@ if ($type == Categorie::TYPE_MEMBER) {
 	if ($user->hasRight("adherent", "read")) {
 		require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
 
-		$permission = $user->rights->adherent->creer;
+		$permission = $user->hasRight('adherent', 'creer');
 
 		$prods = $object->getObjectsInCateg($type, 0, $limit, $offset);
 		if ($prods < 0) {
@@ -769,7 +769,7 @@ if ($type == Categorie::TYPE_MEMBER) {
 
 			print '<br>';
 			$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = '';
-			$newcardbutton = dolGetButtonTitle($langs->trans("AddMember"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/card.php?action=create&memcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->adherent->creer);
+			$newcardbutton = dolGetButtonTitle($langs->trans("AddMember"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/card.php?action=create&memcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->hasRight('adherent', 'creer'));
 			print_barre_liste($langs->trans("Member"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'members', 0, $newcardbutton, '', $limit);
 
 			print "<table class='noborder' width='100%'>\n";
@@ -809,7 +809,7 @@ if ($type == Categorie::TYPE_MEMBER) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Member"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'members');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -896,7 +896,7 @@ if ($type == Categorie::TYPE_CONTACT) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Contact"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'contact');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -978,7 +978,7 @@ if ($type == Categorie::TYPE_ACCOUNT) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Banque"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'bank');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -1061,7 +1061,7 @@ if ($type == Categorie::TYPE_PROJECT) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Project"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'project');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -1138,7 +1138,7 @@ if ($type == Categorie::TYPE_USER) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Users"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'user');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -1202,7 +1202,7 @@ if ($type == Categorie::TYPE_WAREHOUSE) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Warehouse"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'stock');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 
@@ -1281,7 +1281,7 @@ if ($type == Categorie::TYPE_TICKET) {
 		}
 	} else {
 		print_barre_liste($langs->trans("Ticket"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'ticket');
-		accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
+		accessforbidden("NotEnoughPermissions", 0, 0);
 	}
 }
 

+ 16 - 12
htdocs/comm/action/card.php

@@ -25,32 +25,35 @@
  */
 
 /**
- *       \file       htdocs/comm/action/card.php
- *       \ingroup    agenda
- *       \brief      Page for event card
+ *    \file       htdocs/comm/action/card.php
+ *    \ingroup    agenda
+ *    \brief      Page for event card
  */
 
 // Load Dolibarr environment
 require '../../main.inc.php';
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
-require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
+require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
+require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
-require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
+
 
 // Load translation files required by the page
 $langs->loadLangs(array("companies", "other", "commercial", "bills", "orders", "agenda", "mails"));
 
+// Get Parameters
 $action = GETPOST('action', 'aZ09');
 $cancel = GETPOST('cancel', 'alpha');
 $backtopage = GETPOST('backtopage', 'alpha');
@@ -97,6 +100,7 @@ if ($user->socid) {
 $error = GETPOST("error");
 $donotclearsession = GETPOST('donotclearsession') ?GETPOST('donotclearsession') : 0;
 
+// Initialize Objects
 $object = new ActionComm($db);
 $cactioncomm = new CActionComm($db);
 $contact = new Contact($db);

+ 0 - 4
htdocs/comm/action/list.php

@@ -27,10 +27,6 @@
  *		\brief      Page to list actions
  */
 
-if (!defined("NOREDIRECTBYMAINTOLOGIN")) {
-	define('NOREDIRECTBYMAINTOLOGIN', 1);
-}
-
 // Load Dolibarr environment
 require '../../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';

+ 43 - 26
htdocs/comm/action/pertype.php

@@ -23,21 +23,21 @@
 
 
 /**
- *  \file       htdocs/comm/action/pertype.php
- *  \ingroup    agenda
- *  \brief      Tab of calendar events per type
+ *    \file       htdocs/comm/action/pertype.php
+ *    \ingroup    agenda
+ *    \brief      Tab of calendar events per type
  */
 
 // Load Dolibarr environment
 require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
-require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
-require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
+require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
+require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
 
 
 if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) {
@@ -52,28 +52,35 @@ $filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha
 $filtert = GETPOST("search_filtert", "int", 3) ? GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3);
 $usergroup = GETPOST("search_usergroup", "int", 3) ? GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3);
 //if (! ($usergroup > 0) && ! ($filtert > 0)) $filtert = $user->id;
-//$showbirthday = empty($conf->use_javascript_ajax)?GETPOST("showbirthday","int"):1;
-$showbirthday = 0;
+
+// $showbirthday = empty($conf->use_javascript_ajax)?GETPOST("showbirthday","int"):1;
+$showbirthday = 0;    // will be hidden here
 
 // If not choice done on calendar owner, we filter on user.
 if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) {
 	$filtert = $user->id;
 }
 
+// Sorting
 $sortfield = GETPOST('sortfield', 'aZ09comma');
+if (!$sortfield) {
+	$sortfield = "a.datec";
+}
+
 $sortorder = GETPOST('sortorder', 'aZ09comma');
+if (!$sortorder) {
+	$sortorder = "ASC";
+}
+
+// Page
 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
 if (empty($page) || $page == -1) {
 	$page = 0;
 }     // If $page is not defined, or '' or -1
 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
 $offset = $limit * $page;
-if (!$sortorder) {
-	$sortorder = "ASC";
-}
-if (!$sortfield) {
-	$sortfield = "a.datec";
-}
+
+
 
 // Security check
 $socid = GETPOST("search_socid", "int") ?GETPOST("search_socid", "int") : GETPOST("socid", "int");
@@ -84,6 +91,7 @@ if ($socid < 0) {
 	$socid = '';
 }
 
+// Permissions
 $canedit = 1;
 if (empty($user->rights->agenda->myactions->read)) {
 	accessforbidden();
@@ -106,6 +114,7 @@ $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'alpha') : GE
 $type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha');
 $maxprint = ((GETPOST("maxprint", 'int') != '') ? GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW);
 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
+
 // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index)
 if (GETPOST('search_actioncode', 'array')) {
 	$actioncode = GETPOST('search_actioncode', 'array', 3);
@@ -118,11 +127,12 @@ if (GETPOST('search_actioncode', 'array')) {
 
 $dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int'));
 if ($dateselect > 0) {
-	$day = GETPOST('dateselectday', 'int');
+	$day   = GETPOST('dateselectday', 'int');
 	$month = GETPOST('dateselectmonth', 'int');
-	$year = GETPOST('dateselectyear', 'int');
+	$year  = GETPOST('dateselectyear', 'int');
 }
 
+// working hours
 $tmp = empty($conf->global->MAIN_DEFAULT_WORKING_HOURS) ? '9-18' : $conf->global->MAIN_DEFAULT_WORKING_HOURS;
 $tmp = str_replace(' ', '', $tmp); // FIX 7533
 $tmparray = explode('-', $tmp);
@@ -138,6 +148,7 @@ if ($end_h <= $begin_h) {
 	$end_h = $begin_h + 1;
 }
 
+// working days
 $tmp = empty($conf->global->MAIN_DEFAULT_WORKING_DAYS) ? '1-5' : $conf->global->MAIN_DEFAULT_WORKING_DAYS;
 $tmp = str_replace(' ', '', $tmp); // FIX 7533
 $tmparray = explode('-', $tmp);
@@ -151,19 +162,24 @@ if (empty($mode) && !GETPOSTISSET('mode')) {
 	$mode = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW);
 }
 
+// View by month
 if (GETPOST('viewcal', 'alpha') && $mode != 'show_day' && $mode != 'show_week' && $mode != 'show_peruser') {
 	$mode = 'show_month'; $day = '';
-}                                                   // View by month
+}
+// View by week
 if (GETPOST('viewweek', 'alpha') || $mode == 'show_week') {
 	$mode = 'show_week'; $week = ($week ? $week : date("W")); $day = ($day ? $day : date("d"));
-}  // View by week
+}
+// View by day
 if (GETPOST('viewday', 'alpha') || $mode == 'show_day') {
 	$mode = 'show_day'; $day = ($day ? $day : date("d"));
-}                                  // View by day
+}
+// View by year
 if (GETPOST('viewyear', 'alpha') || $mode == 'show_year') {
 	$mode = 'show_year';
-}                                  // View by year
+}
 
+// Initialize object
 $object = new ActionComm($db);
 
 // Load translation files required by the page
@@ -219,6 +235,7 @@ $parameters = array(
 	'resourceid' => $resourceid,
 	'usergroup' => $usergroup,
 );
+
 $reshook = $hookmanager->executeHooks('beforeAgendaPerType', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
 if ($reshook < 0) {
 	setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
@@ -227,14 +244,14 @@ if ($reshook < 0) {
 $form = new Form($db);
 $companystatic = new Societe($db);
 
-$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&oacute;dulo_Agenda';
+$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&oacute;dulo_Agenda|DE:Modul_Terminplanung';
 llxHeader('', $langs->trans("Agenda"), $help_url);
 
 $now = dol_now();
 $nowarray = dol_getdate($now);
-$nowyear = $nowarray['year'];
+$nowyear  = $nowarray['year'];
 $nowmonth = $nowarray['mon'];
-$nowday = $nowarray['mday'];
+$nowday   = $nowarray['mday'];
 
 
 // Define list of all external calendars (global setup)
@@ -247,7 +264,7 @@ $first_year  = $year;
 
 $week = $prev['week'];
 
-$day = (int) $day;
+$day  = (int) $day;
 $next = dol_get_next_day($day, $month, $year);
 $next_year  = $year + 1;
 $next_month = $month;

+ 3 - 0
htdocs/compta/bank/annuel.php

@@ -193,6 +193,9 @@ for ($mois = 1; $mois < 13; $mois++) {
 	print '<tr class="oddeven">';
 	print "<td>".dol_print_date(dol_mktime(1, 1, 1, $mois, 1, 2000), "%B")."</td>";
 	for ($annee = $year_start; $annee <= $year_end; $annee++) {
+		$totsorties[$annee] = 0;
+		$totentrees[$annee] = 0;
+
 		$case = sprintf("%04s-%02s", $annee, $mois);
 
 		print '<td class="right" width="10%">&nbsp;';

+ 1 - 1
htdocs/compta/bank/bankentries_list.php

@@ -1278,7 +1278,7 @@ if ($resql) {
 				}
 				// Extra fields
 				$element = 'banktransaction';
-				if (is_array($extrafields->attributes[$element]['label']) && count($extrafields->attributes[$element]['label'])) {
+				if (!empty($extrafields->attributes[$element]['label']) && is_array($extrafields->attributes[$element]['label']) && count($extrafields->attributes[$element]['label'])) {
 					foreach ($extrafields->attributes[$element]['label'] as $key => $val) {
 						if (!empty($arrayfields["ef.".$key]['checked'])) {
 							if (!empty($arrayfields[$key]['checked'])) {

+ 6 - 4
htdocs/compta/bank/transfer.php

@@ -22,9 +22,9 @@
  */
 
 /**
- *		\file       htdocs/compta/bank/transfer.php
- *		\ingroup    banque
- *		\brief      Page de saisie d'un virement
+ *    \file       htdocs/compta/bank/transfer.php
+ *    \ingroup    bank
+ *    \brief      Page for entering a bank transfer
  */
 
 // Load Dolibarr environment
@@ -33,7 +33,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
 
 // Load translation files required by the page
-$langs->loadLangs(array("banks", "categories", "multicurrency"));
+$langs->loadLangs(array('banks', 'categories', 'multicurrency'));
+
+
 $socid = 0;
 if ($user->socid > 0) {
 	$socid = $user->socid;

+ 1 - 1
htdocs/compta/bank/treso.php

@@ -294,7 +294,7 @@ if (GETPOST("account") || GETPOST("ref")) {
 				}
 				print "</td>";
 				print "<td>".$ref."</td>";
-				if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) {
+				if (getDolGlobalString("MULTICOMPANY_INVOICE_SHARING_ENABLED")) {
 					if ($tmpobj->family == 'invoice') {
 						$mc->getInfo($tmpobj->entity);
 						print "<td>".$mc->label."</td>";

+ 2 - 0
htdocs/compta/paiement/cheque/list.php

@@ -64,6 +64,8 @@ if (!$sortfield) {
 
 $year = GETPOST("year");
 $month = GETPOST("month");
+$optioncss = GETPOST('optioncss', 'alpha');
+$view = GETPOST("view", 'alpha');
 
 $form = new Form($db);
 $formother = new FormOther($db);

+ 2 - 1
htdocs/compta/prelevement/create.php

@@ -62,6 +62,7 @@ $offset = $limit * $page;
 $hookmanager->initHooks(array('directdebitcreatecard', 'globalcard'));
 
 // Security check
+$socid = GETPOST('socid', 'int');
 if ($user->socid) {
 	$socid = $user->socid;
 }
@@ -72,7 +73,7 @@ if ($type == 'bank-transfer') {
 }
 
 $error = 0;
-
+$option = "";
 
 /*
  * Actions

+ 2 - 0
htdocs/compta/prelevement/orders_list.php

@@ -53,6 +53,8 @@ if (!$sortfield) {
 	$sortfield = "p.datec";
 }
 
+$optioncss = GETPOST('optioncss', 'alpha');
+
 // Get supervariables
 $statut = GETPOST('statut', 'int');
 $search_ref = GETPOST('search_ref', 'alpha');

+ 2 - 2
htdocs/core/actions_linkedfiles.inc.php

@@ -41,8 +41,8 @@ if ((GETPOST('sendit', 'alpha')
 	|| ($action == 'confirm_deletefile' && $confirm == 'yes')
 	|| ($action == 'confirm_updateline' && GETPOST('save', 'alpha') && GETPOST('link', 'alpha'))
 	|| ($action == 'renamefile' && GETPOST('renamefilesave', 'alpha'))) && empty($permissiontoadd)) {
-	dol_syslog('The file actions_linkedfiles.inc.php was included but paramater $permissiontoadd as not set before.');
-	print 'The file actions_linkedfiles.inc.php was included but paramater $permissiontoadd as not set before.';
+	dol_syslog('The file actions_linkedfiles.inc.php was included but parameter $permissiontoadd was not set before.');
+	print 'The file actions_linkedfiles.inc.php was included but parameter $permissiontoadd was not set before.';
 	die;
 }
 

+ 6 - 3
htdocs/core/ajax/objectonoff.php

@@ -1,5 +1,6 @@
 <?php
-/*
+/* Copyright (C) 2015-2022 Laurent Destailleur  <eldy@users.sourceforge.net>
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
@@ -66,13 +67,15 @@ if (!empty($user->socid)) {
 	$socid = $user->socid;
 }
 
+//$user->rights->societe->lire = 0;$user->rights->fournisseur->lire = 0;
+//restrictedArea($user, 'societe', $id);
+
 if (in_array($field, array('status'))) {
 	restrictedArea($user, $element, $id);
 } elseif ($element == 'product' && in_array($field, array('tosell', 'tobuy', 'tobatch'))) {	// Special case for products
 	restrictedArea($user, 'produit|service', $id, 'product&product', '', '', 'rowid');
 } else {
-	accessforbidden("Bad value for combination of parameters element/field.", 0, 0, 1);
-	exit;
+	httponly_accessforbidden("Bad value for combination of parameters element/field.");
 }
 
 

+ 1 - 3
htdocs/core/ajax/onlineSign.php

@@ -74,9 +74,7 @@ if ($type == 'proposal') {
 }
 
 if (empty($SECUREKEY) || !dol_verifyHash($securekeyseed.$type.$ref.(!isModEnabled('multicompany') ? '' : $entity), $SECUREKEY, '0')) {
-	http_response_code(403);
-	print 'Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref);
-	exit(-1);
+	httponly_accessforbidden('Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref), 403);
 }
 
 

+ 1 - 0
htdocs/core/ajax/selectsearchbox.php

@@ -40,6 +40,7 @@ if (!isset($usedbyinclude) || empty($usedbyinclude)) {
 		define('NOREQUIREAJAX', '1');
 	}
 	if (!defined('NOREDIRECTBYMAINTOLOGIN')) {
+		// Disable redirect to main login because the selectsearch must not ask a login
 		define('NOREDIRECTBYMAINTOLOGIN', '1');
 	}
 

+ 809 - 0
htdocs/core/class/commoninvoice.class.php

@@ -823,6 +823,815 @@ abstract class CommonInvoice extends CommonObject
 		}
 	}
 
+
+	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+	/**
+	 *	Create a withdrawal request for a direct debit order or a credit transfer order.
+	 *  Use the remain to pay excluding all existing open direct debit requests.
+	 *
+	 *	@param      User	$fuser      	User asking the direct debit transfer
+	 *  @param		float	$amount			Amount we request direct debit for
+	 *  @param		string	$type			'direct-debit' or 'bank-transfer'
+	 *  @param		string	$sourcetype		Source ('facture' or 'supplier_invoice')
+	 *	@return     int         			<0 if KO, >0 if OK
+	 */
+	public function demande_prelevement_stripe($fuser, $amount = 0, $type = 'direct-debit', $sourcetype = 'facture')
+	{
+		// phpcs:enable
+		global $conf, $mysoc, $user, $langs;
+
+		if (empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
+			//exit
+			return 0;
+		}
+
+		$error = 0;
+
+		dol_syslog(get_class($this)."::demande_prelevement_stripe 0", LOG_DEBUG);
+
+		if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) {
+			require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
+			$bac = new CompanyBankAccount($this->db);
+			$bac->fetch(0, $this->socid);
+
+			$sql = 'SELECT count(*)';
+			$sql .= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
+			$sql .= ' WHERE fk_facture = '.((int) $this->id);
+			$sql .= ' AND ext_payment_id IS NULL'; // To exclude record done for some online payments
+			$sql .= ' AND traite = 0';
+
+			dol_syslog(get_class($this)."::demande_prelevement_stripe 1", LOG_DEBUG);
+			$resql = $this->db->query($sql);
+			if ($resql) {
+				$row = $this->db->fetch_row($resql);
+
+				if ($row[0] == 0) {
+					$now = dol_now();
+
+					$totalpaye = $this->getSommePaiement();
+					$totalcreditnotes = $this->getSumCreditNotesUsed();
+					$totaldeposits = $this->getSumDepositsUsed();
+					//print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
+
+					// We can also use bcadd to avoid pb with floating points
+					// For example print 239.2 - 229.3 - 9.9; does not return 0.
+					//$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
+					//$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
+					if (empty($amount)) {
+						$amount = price2num($this->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
+					}
+
+					if (is_numeric($amount) && $amount != 0) {
+						require_once DOL_DOCUMENT_ROOT.'/societe/class/companypaymentmode.class.php';
+						$companypaymentmode = new CompanyPaymentMode($this->db);
+						$companypaymentmode->fetch($bac->id);
+
+						dol_syslog(get_class($this)."::demande_prelevement_stripe amount=$amount, companypaymentmode = " . $companypaymentmode->id, LOG_DEBUG);
+
+						//Start code from sellyoursaas
+						$service = 'StripeTest';
+						$servicestatus = 0;
+						if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
+							$service = 'StripeLive';
+							$servicestatus = 1;
+						}
+
+						$langs->load("agenda");
+						dol_syslog("doTakePaymentStripeForThirdparty service=" . $service . " servicestatus=" . $servicestatus . " thirdparty_id=" . $this->socid . " companypaymentmode=" . $companypaymentmode->id . " noemailtocustomeriferror=" . $noemailtocustomeriferror . " nocancelifpaymenterror=" . $nocancelifpaymenterror . " calledinmyaccountcontext=" . $calledinmyaccountcontext);
+
+						$this->stripechargedone = 0;
+						$this->stripechargeerror = 0;
+						$now = dol_now();
+
+						$currency = $conf->currency;
+
+						global $stripearrayofkeysbyenv;
+						global $savstripearrayofkeysbyenv;
+
+						$errorforinvoice = 0;     // We reset the $errorforinvoice at each invoice loop
+
+						$this->fetch_thirdparty();
+
+						dol_syslog("--- Process invoice thirdparty_id=" . $this->id . ", thirdparty_name=" . $this->thirdparty->name . " id=" . $this->id . ", ref=" . $this->ref . ", datef=" . dol_print_date($this->date, 'dayhourlog'), LOG_DEBUG);
+
+						$alreadypayed = $this->getSommePaiement();
+						$amount_credit_notes_included = $this->getSumCreditNotesUsed();
+						$amounttopay = $this->total_ttc - $alreadypayed - $amount_credit_notes_included;
+
+						// Correct the amount according to unit of currency
+						// See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
+						$arrayzerounitcurrency = ['BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'];
+						$amountstripe = $amounttopay;
+						if (!in_array($currency, $arrayzerounitcurrency)) {
+							$amountstripe = $amountstripe * 100;
+						}
+
+						if ($amountstripe > 0) {
+							try {
+								//var_dump($companypaymentmode);
+								dol_syslog("We will try to pay with companypaymentmodeid=" . $companypaymentmode->id . " stripe_card_ref=" . $companypaymentmode->stripe_card_ref . " mode=" . $companypaymentmode->status, LOG_DEBUG);
+
+								$thirdparty = new Societe($this->db);
+								$resultthirdparty = $thirdparty->fetch($this->socid);
+
+								include_once DOL_DOCUMENT_ROOT . '/stripe/class/stripe.class.php';        // This include the include of htdocs/stripe/config.php
+								// So it inits or erases the $stripearrayofkeysbyenv
+								$stripe = new Stripe($this->db);
+
+								if (empty($savstripearrayofkeysbyenv)) {
+									$savstripearrayofkeysbyenv = $stripearrayofkeysbyenv;
+								}
+								dol_syslog("Current Stripe environment is " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key']);
+								dol_syslog("Current Saved Stripe environment is " . $savstripearrayofkeysbyenv[$servicestatus]['publishable_key']);
+
+								$foundalternativestripeaccount = '';
+
+								// Force stripe to another value (by default this value is empty)
+								if (!empty($thirdparty->array_options['options_stripeaccount'])) {
+									dol_syslog("The thirdparty id=" . $thirdparty->id . " has a dedicated Stripe Account, so we switch to it.");
+
+									$tmparray = explode('@', $thirdparty->array_options['options_stripeaccount']);
+									if (!empty($tmparray[1])) {
+										$tmparray2 = explode(':', $tmparray[1]);
+										if (!empty($tmparray2[3])) {
+											$stripearrayofkeysbyenv = [
+												0 => [
+													"publishable_key" => $tmparray2[0],
+													"secret_key" => $tmparray2[1]
+												],
+												1 => [
+													"publishable_key" => $tmparray2[2],
+													"secret_key" => $tmparray2[3]
+												]
+											];
+
+											$stripearrayofkeys = $stripearrayofkeysbyenv[$servicestatus];
+											\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
+
+											$foundalternativestripeaccount = $tmparray[0];    // Store the customer id
+
+											dol_syslog("We use now customer=" . $foundalternativestripeaccount . " publishable_key=" . $stripearrayofkeys['publishable_key'], LOG_DEBUG);
+										}
+									}
+
+									if (!$foundalternativestripeaccount) {
+										$stripearrayofkeysbyenv = $savstripearrayofkeysbyenv;
+
+										$stripearrayofkeys = $savstripearrayofkeysbyenv[$servicestatus];
+										\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
+										dol_syslog("We found a bad value for Stripe Account for thirdparty id=" . $thirdparty->id . ", so we ignore it and keep using the global one, so " . $stripearrayofkeys['publishable_key'], LOG_WARNING);
+									}
+								} else {
+									$stripearrayofkeysbyenv = $savstripearrayofkeysbyenv;
+
+									$stripearrayofkeys = $savstripearrayofkeysbyenv[$servicestatus];
+									\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
+									dol_syslog("The thirdparty id=" . $thirdparty->id . " has no dedicated Stripe Account, so we use global one, so " . json_encode($stripearrayofkeys), LOG_DEBUG);
+								}
+
+
+								dol_syslog("get stripe account", LOG_DEBUG);
+								$stripeacc = $stripe->getStripeAccount($service, $this->socid);								// Get Stripe OAuth connect account if it exists (no network access here)
+								dol_syslog("get stripe account return " . json_encode($stripeacc), LOG_DEBUG);
+
+								if ($foundalternativestripeaccount) {
+									if (empty($stripeacc)) {				// If the Stripe connect account not set, we use common API usage
+										$customer = \Stripe\Customer::retrieve(['id' => "$foundalternativestripeaccount", 'expand[]' => 'sources']);
+									} else {
+										$customer = \Stripe\Customer::retrieve(['id' => "$foundalternativestripeaccount", 'expand[]' => 'sources'], ["stripe_account" => $stripeacc]);
+									}
+								} else {
+									$customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 0);
+									if (empty($customer) && !empty($stripe->error)) {
+										$this->errors[] = $stripe->error;
+									}
+									/*if (!empty($customer) && empty($customer->sources)) {
+									 $customer = null;
+									 $this->errors[] = '\Stripe\Customer::retrieve did not returned the sources';
+									 }*/
+								}
+
+								// $nbhoursbetweentries = (empty($conf->global->SELLYOURSAAS_NBHOURSBETWEENTRIES) ? 49 : $conf->global->SELLYOURSAAS_NBHOURSBETWEENTRIES);				// Must have more that 48 hours + 1 between each try (so 1 try every 3 daily batch)
+								// $nbdaysbeforeendoftries = (empty($conf->global->SELLYOURSAAS_NBDAYSBEFOREENDOFTRIES) ? 35 : $conf->global->SELLYOURSAAS_NBDAYSBEFOREENDOFTRIES);
+								$labeltouse = '';
+								$postactionmessages = [];
+
+								if ($resultthirdparty > 0 && !empty($customer)) {
+									if (!$error && !empty($this->array_options['options_delayautopayment']) && $this->array_options['options_delayautopayment'] > $now && empty($calledinmyaccountcontext)) {
+										$errmsg = 'Payment try was canceled (invoice qualified by the automatic payment was delayed after the ' . dol_print_date($this->array_options['options_delayautopayment'], 'day') . ')';
+										dol_syslog($errmsg, LOG_DEBUG);
+
+										$error++;
+										$errorforinvoice++;
+										$this->errors[] = $errmsg;
+									}
+									// if (!$error && ($this->date < ($now - ($nbdaysbeforeendoftries * 24 * 3600)))                                 // We try until we reach $nbdaysbeforeendoftries
+									// 	&& ($this->date < ($now - (62 * 24 * 3600)) || $this->date > ($now - (60 * 24 * 3600)))     // or when we have 60 days
+									// 	&& ($this->date < ($now - (92 * 24 * 3600)) || $this->date > ($now - (90 * 24 * 3600)))     // or when we have 90 days
+									// 	&& empty($nocancelifpaymenterror)) {
+									// 	$errmsg = 'Payment try was canceled (invoice date is older than ' . $nbdaysbeforeendoftries . ' days and not 60 days old and not 90 days old) - You can still take payment from backoffice.';
+										// 	dol_syslog($errmsg, LOG_DEBUG);
+
+										// 	$error++;
+										// 	$errorforinvoice++;
+										// 	$this->errors[] = $errmsg;
+										// }
+										// if (!$error && empty($nocancelifpaymenterror)) {	// If we are not in a mode that ask to avoid cancelation, we cancel payment.
+										// 	// Test if last AC_PAYMENT_STRIPE_KO event is an old error lower than $nbhoursbetweentries hours.
+										// 	$recentfailedpayment = false;
+										// 	$sqlonevents = 'SELECT COUNT(*) as nb FROM ' . MAIN_DB_PREFIX . 'actioncomm WHERE fk_soc = ' . ((int) $thirdparty->id) . " AND code ='AC_PAYMENT_STRIPE_KO' AND datep > '" . $this->db->idate($now - ($nbhoursbetweentries * 3600)) . "'";
+										// 	$resqlonevents = $this->db->query($sqlonevents);
+										// 	if ($resqlonevents) {
+										// 		$obj = $this->db->fetch_object($resqlonevents);
+										// 		if ($obj && $obj->nb > 0) {
+										// 			$recentfailedpayment = true;
+										// 		}
+										// 	}
+
+										// 	if ($recentfailedpayment) {
+										// 		$errmsg = 'Payment try was canceled (recent payment, in last ' . $nbhoursbetweentries . ' hours, with error AC_PAYMENT_STRIPE_KO for this customer)';
+										// 		dol_syslog($errmsg, LOG_DEBUG);
+
+										// 		$error++;
+										// 		$errorforinvoice++;
+										// 		$this->errors[] = $errmsg;
+										// 	}
+										// }
+
+									if (!$error) {	// Payment was not canceled
+										//erics card or sepa ?
+										$sepaMode = false;
+										if ($companypaymentmode->type == 'ban') {
+											$sepaMode = true;
+											$stripecard = $stripe->sepaStripe($customer, $companypaymentmode, $stripeacc, $servicestatus, 0);
+										} else {
+											$stripecard = $stripe->cardStripe($customer, $companypaymentmode, $stripeacc, $servicestatus, 0);
+										}
+
+										if ($stripecard) {  // Can be card_... (old mode) or pm_... (new mode)
+											$FULLTAG = 'INV=' . $this->id . '-CUS=' . $thirdparty->id;
+											$description = 'Stripe payment from doTakePaymentStripeForThirdparty: ' . $FULLTAG . ' ref=' . $this->ref;
+
+											$stripefailurecode = '';
+											$stripefailuremessage = '';
+											$stripefailuredeclinecode = '';
+
+											if (preg_match('/^card_/', $stripecard->id)) { // Using old method
+												dol_syslog("* Create charge on card " . $stripecard->id . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
+
+												$ipaddress = getUserRemoteIP();
+
+												$charge = null;		// Force reset of $charge, so, if already set from a previous fetch, it will be empty even if there is an exception at next step
+												try {
+													$charge = \Stripe\Charge::create([
+														'amount' => price2num($amountstripe, 'MU'),
+														'currency' => $currency,
+														'capture' => true,							// Charge immediatly
+														'description' => $description,
+														'metadata' => ["FULLTAG" => $FULLTAG, 'Recipient' => $mysoc->name, 'dol_version' => DOL_VERSION, 'dol_entity' => $conf->entity, 'ipaddress' => $ipaddress],
+														'customer' => $customer->id,
+														//'customer' => 'bidon_to_force_error',		// To use to force a stripe error
+														'source' => $stripecard,
+														'statement_descriptor' => dol_trunc('INV=' . $this->id, 10, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt (company + description)
+													]);
+												} catch (\Stripe\Error\Card $e) {
+													// Since it's a decline, Stripe_CardError will be caught
+													$body = $e->getJsonBody();
+													$err = $body['error'];
+
+													$stripefailurecode = $err['code'];
+													$stripefailuremessage = $err['message'];
+													$stripefailuredeclinecode = $err['decline_code'];
+												} catch (Exception $e) {
+													$stripefailurecode = 'UnknownChargeError';
+													$stripefailuremessage = $e->getMessage();
+												}
+											} else { // Using new SCA method
+												if ($sepaMode)
+													dol_syslog("* Create payment on SEPA " . $stripecard->id . ", amounttopay=" . $amounttopay . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
+												else dol_syslog("* Create payment on card " . $stripecard->id . ", amounttopay=" . $amounttopay . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
+
+														// Create payment intent and charge payment (confirmnow = true)
+														$paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1);
+
+														$charge = new stdClass();
+														//erics add processing sepa is like success ?
+												if ($paymentintent->status === 'succeeded' || $paymentintent->status === 'processing') {
+													$charge->status = 'ok';
+													$charge->id = $paymentintent->id;
+													$charge->customer = $customer->id;
+												} elseif ($paymentintent->status === 'requires_action') {
+													//paymentintent->status may be => 'requires_action' (no error in such a case)
+													dol_syslog(var_export($paymentintent, true), LOG_DEBUG);
+
+													$charge->status = 'failed';
+													$charge->customer = $customer->id;
+													$charge->failure_code = $stripe->code;
+													$charge->failure_message = $stripe->error;
+													$charge->failure_declinecode = $stripe->declinecode;
+													$stripefailurecode = $stripe->code;
+													$stripefailuremessage = 'Action required. Contact the support at ';// . $conf->global->SELLYOURSAAS_MAIN_EMAIL;
+													$stripefailuredeclinecode = $stripe->declinecode;
+												} else {
+													dol_syslog(var_export($paymentintent, true), LOG_DEBUG);
+
+													$charge->status = 'failed';
+													$charge->customer = $customer->id;
+													$charge->failure_code = $stripe->code;
+													$charge->failure_message = $stripe->error;
+													$charge->failure_declinecode = $stripe->declinecode;
+													$stripefailurecode = $stripe->code;
+													$stripefailuremessage = $stripe->error;
+													$stripefailuredeclinecode = $stripe->declinecode;
+												}
+
+														//var_dump("stripefailurecode=".$stripefailurecode." stripefailuremessage=".$stripefailuremessage." stripefailuredeclinecode=".$stripefailuredeclinecode);
+														//exit;
+											}
+
+											// Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
+											if (empty($charge) || $charge->status == 'failed') {
+												dol_syslog('Failed to charge card or payment mode ' . $stripecard->id . ' stripefailurecode=' . $stripefailurecode . ' stripefailuremessage=' . $stripefailuremessage . ' stripefailuredeclinecode=' . $stripefailuredeclinecode, LOG_WARNING);
+
+												// Save a stripe payment was in error
+												$this->stripechargeerror++;
+
+												$error++;
+												$errorforinvoice++;
+												$errmsg = $langs->trans("FailedToChargeCard");
+												if (!empty($charge)) {
+													if ($stripefailuredeclinecode == 'authentication_required') {
+														$errauthenticationmessage = $langs->trans("ErrSCAAuthentication");
+														$errmsg = $errauthenticationmessage;
+													} elseif (in_array($stripefailuredeclinecode, ['insufficient_funds', 'generic_decline'])) {
+														$errmsg .= ': ' . $charge->failure_code;
+														$errmsg .= ($charge->failure_message ? ' - ' : '') . ' ' . $charge->failure_message;
+														if (empty($stripefailurecode)) {
+															$stripefailurecode = $charge->failure_code;
+														}
+														if (empty($stripefailuremessage)) {
+															$stripefailuremessage = $charge->failure_message;
+														}
+													} else {
+														$errmsg .= ': failure_code=' . $charge->failure_code;
+														$errmsg .= ($charge->failure_message ? ' - ' : '') . ' failure_message=' . $charge->failure_message;
+														if (empty($stripefailurecode)) {
+															$stripefailurecode = $charge->failure_code;
+														}
+														if (empty($stripefailuremessage)) {
+															$stripefailuremessage = $charge->failure_message;
+														}
+													}
+												} else {
+													$errmsg .= ': ' . $stripefailurecode . ' - ' . $stripefailuremessage;
+													$errmsg .= ($stripefailuredeclinecode ? ' - ' . $stripefailuredeclinecode : '');
+												}
+
+												$description = 'Stripe payment ERROR from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
+												$postactionmessages[] = $errmsg . ' (' . $stripearrayofkeys['publishable_key'] . ')';
+												$this->errors[] = $errmsg;
+											} else {
+												dol_syslog('Successfuly charge card ' . $stripecard->id);
+
+												$postactionmessages[] = 'Success to charge card (' . $charge->id . ' with ' . $stripearrayofkeys['publishable_key'] . ')';
+
+												// Save a stripe payment was done in realy life so later we will be able to force a commit on recorded payments
+												// even if in batch mode (method doTakePaymentStripe), we will always make all action in one transaction with a forced commit.
+												$this->stripechargedone++;
+
+												// Default description used for label of event. Will be overwrite by another value later.
+												$description = 'Stripe payment OK (' . $charge->id . ') from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
+
+												$db = $this->db;
+
+												$ipaddress = getUserRemoteIP();
+
+												$TRANSACTIONID = $charge->id;
+												$currency = $conf->currency;
+												$paymentmethod = 'stripe';
+												$emetteur_name = $charge->customer;
+
+												// Same code than into paymentok.php...
+
+												$paymentTypeId = 0;
+												if ($paymentmethod == 'paybox') {
+													$paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS;
+												}
+												if ($paymentmethod == 'paypal') {
+													$paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS;
+												}
+												if ($paymentmethod == 'stripe') {
+													$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
+												}
+												if (empty($paymentTypeId)) {
+													//erics
+													if ($sepaMode) {
+														$paymentType = 'PRE';
+													} else {
+														$paymentType = $_SESSION["paymentType"];
+														if (empty($paymentType)) {
+															$paymentType = 'CB';
+														}
+													}
+													$paymentTypeId = dol_getIdFromCode($this->db, $paymentType, 'c_paiement', 'code', 'id', 1);
+												}
+
+												$currencyCodeType = $currency;
+
+												$ispostactionok = 1;
+
+												// Creation of payment line
+												include_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
+												$paiement = new Paiement($this->db);
+												$paiement->datepaye = $now;
+												$paiement->date = $now;
+												if ($currencyCodeType == $conf->currency) {
+													$paiement->amounts = [$this->id => $amounttopay];   // Array with all payments dispatching with invoice id
+												} else {
+													$paiement->multicurrency_amounts = [$this->id => $amounttopay];   // Array with all payments dispatching
+
+													$postactionmessages[] = 'Payment was done in a different currency than currency expected of company';
+													$ispostactionok = -1;
+													// Not yet supported, so error
+													$error++;
+													$errorforinvoice++;
+												}
+												$paiement->paiementid = $paymentTypeId;
+												$paiement->num_paiement = '';
+												$paiement->num_payment = '';
+												// Add a comment with keyword 'SellYourSaas' in text. Used by trigger.
+												$paiement->note_public = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID;
+												$paiement->note_private = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID;
+												$paiement->ext_payment_id = $charge->id . ':' . $customer->id . '@' . $stripearrayofkeys['publishable_key'];
+												$paiement->ext_payment_site = 'stripe';
+
+												if (!$errorforinvoice) {
+													dol_syslog('* Record payment for invoice id ' . $this->id . '. It includes closing of invoice and regenerating document');
+
+													// This include closing invoices to 'paid' (and trigger including unsuspending) and regenerating document
+													$paiement_id = $paiement->create($user, 1);
+													if ($paiement_id < 0) {
+														$postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("<br>\n", $paiement->errors);
+														$ispostactionok = -1;
+														$error++;
+														$errorforinvoice++;
+													} else {
+														$postactionmessages[] = 'Payment created';
+													}
+
+													dol_syslog("The payment has been created for invoice id " . $this->id);
+												}
+
+												if (!$errorforinvoice && !empty($conf->banque->enabled)) {
+													dol_syslog('* Add payment to bank');
+
+													$bankaccountid = 0;
+													if ($paymentmethod == 'paybox') {
+														$bankaccountid = $conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS;
+													}
+													if ($paymentmethod == 'paypal') {
+														$bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
+													}
+													if ($paymentmethod == 'stripe') {
+														$bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
+													}
+
+													if ($bankaccountid > 0) {
+														$label = '(CustomerInvoicePayment)';
+														if ($this->type == Facture::TYPE_CREDIT_NOTE) {
+															$label = '(CustomerInvoicePaymentBack)';
+														}  // Refund of a credit note
+														$result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, $emetteur_name, '');
+														if ($result < 0) {
+															$postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("<br>\n", $paiement->errors);
+															$ispostactionok = -1;
+															$error++;
+															$errorforinvoice++;
+														} else {
+															$postactionmessages[] = 'Bank transaction of payment created (by doTakePaymentStripeForThirdparty)';
+														}
+													} else {
+														$postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.';
+														$ispostactionok = -1;
+														$error++;
+														$errorforinvoice++;
+													}
+												}
+
+												if ($ispostactionok < 1) {
+													$description = 'Stripe payment OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') but post action KO from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
+												} else {
+													$description = 'Stripe payment+post action OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
+												}
+											}
+
+											$object = $invoice;
+
+											// Send emails
+											$labeltouse = 'InvoicePaymentSuccess';
+											$sendemailtocustomer = 1;
+
+											if (empty($charge) || $charge->status == 'failed') {
+												$labeltouse = 'InvoicePaymentFailure';
+												if ($noemailtocustomeriferror) {
+													$sendemailtocustomer = 0;
+												}		// $noemailtocustomeriferror is set when error already reported on myaccount screen
+											}
+
+											// Track an event
+											if (empty($charge) || $charge->status == 'failed') {
+												$actioncode = 'PAYMENT_STRIPE_KO';
+												$extraparams = $stripefailurecode;
+												$extraparams .= (($extraparams && $stripefailuremessage) ? ' - ' : '') . $stripefailuremessage;
+												$extraparams .= (($extraparams && $stripefailuredeclinecode) ? ' - ' : '') . $stripefailuredeclinecode;
+											} else {
+												$actioncode = 'PAYMENT_STRIPE_OK';
+												$extraparams = '';
+											}
+										} else {
+											$error++;
+											$errorforinvoice++;
+											dol_syslog("No card or payment method found for this stripe customer " . $customer->id, LOG_WARNING);
+											$this->errors[] = 'Failed to get card | payment method for stripe customer = ' . $customer->id;
+
+											$labeltouse = 'InvoicePaymentFailure';
+											$sendemailtocustomer = 1;
+											if ($noemailtocustomeriferror) {
+												$sendemailtocustomer = 0;
+											}		// $noemailtocustomeriferror is set when error already reported on myaccount screen
+
+											$description = 'Failed to find or use the payment mode - no credit card defined for the customer account';
+											$stripefailurecode = 'BADPAYMENTMODE';
+											$stripefailuremessage = 'Failed to find or use the payment mode - no credit card defined for the customer account';
+											$postactionmessages[] = $description . ' (' . $stripearrayofkeys['publishable_key'] . ')';
+
+											$object = $invoice;
+
+											$actioncode = 'PAYMENT_STRIPE_KO';
+											$extraparams = '';
+										}
+									} else {
+										// If error because payment was canceled for a logical reason, we do nothing (no email and no event added)
+										$labeltouse = '';
+										$sendemailtocustomer = 0;
+
+										$description = '';
+										$stripefailurecode = '';
+										$stripefailuremessage = '';
+
+										$object = $invoice;
+
+										$actioncode = '';
+										$extraparams = '';
+									}
+								} else {	// Else of the   if ($resultthirdparty > 0 && ! empty($customer)) {
+									if ($resultthirdparty <= 0) {
+										dol_syslog('SellYourSaasUtils Failed to load customer for thirdparty_id = ' . $thirdparty->id, LOG_WARNING);
+										$this->errors[] = 'Failed to load customer for thirdparty_id = ' . $thirdparty->id;
+									} else { // $customer stripe not found
+										dol_syslog('SellYourSaasUtils Failed to get Stripe customer id for thirdparty_id = ' . $thirdparty->id . " in mode " . $servicestatus . " in Stripe env " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key'], LOG_WARNING);
+										$this->errors[] = 'Failed to get Stripe customer id for thirdparty_id = ' . $thirdparty->id . " in mode " . $servicestatus . " in Stripe env " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key'];
+									}
+									$error++;
+									$errorforinvoice++;
+
+									$labeltouse = 'InvoicePaymentFailure';
+									$sendemailtocustomer = 1;
+									if ($noemailtocustomeriferror) {
+										$sendemailtocustomer = 0;
+									}		// $noemailtocustomeriferror is set when error already reported on myaccount screen
+
+									$description = 'Failed to find or use your payment mode (no payment mode for this customer id)';
+									$stripefailurecode = 'BADPAYMENTMODE';
+									$stripefailuremessage = 'Failed to find or use your payment mode (no payment mode for this customer id)';
+									$postactionmessages = [];
+
+									$object = $invoice;
+
+									$actioncode = 'PAYMENT_STRIPE_KO';
+									$extraparams = '';
+								}
+
+									// Send email + create action after
+								if ($sendemailtocustomer && $labeltouse) {
+									dol_syslog("* Send email with result of payment - " . $labeltouse);
+
+									// Set output language
+									$outputlangs = new Translate('', $conf);
+									$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
+									$outputlangs->loadLangs(["main", "members", "bills"]);
+
+									// Get email content from templae
+									$arraydefaultmessage = null;
+
+									include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
+									$formmail = new FormMail($this->db);
+
+									if (!empty($labeltouse)) {
+										$arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'facture_send', $user, $outputlangs, 0, 1, $labeltouse);
+									}
+
+									if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
+										$subject = $arraydefaultmessage->topic;
+										$msg = $arraydefaultmessage->content;
+									}
+
+									$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
+
+									//$substitutionarray['__SELLYOURSAAS_PAYMENT_ERROR_DESC__'] = $stripefailurecode . ' ' . $stripefailuremessage;
+
+									complete_substitutions_array($substitutionarray, $outputlangs, $object);
+
+									// Set the property ->ref_customer with ref_customer of contract so __REF_CLIENT__ will be replaced in email content
+									// Search contract linked to invoice
+									$foundcontract = null;
+									$this->fetchObjectLinked();
+									if (is_array($this->linkedObjects['contrat']) && count($this->linkedObjects['contrat']) > 0) {
+										//dol_sort_array($object->linkedObjects['facture'], 'date');
+										foreach ($this->linkedObjects['contrat'] as $idcontract => $contract) {
+											$substitutionarray['__CONTRACT_REF__'] = $contract->ref_customer;
+											$substitutionarray['__REFCLIENT__'] = $contract->ref_customer;	// For backward compatibility
+											$substitutionarray['__REF_CLIENT__'] = $contract->ref_customer;
+											$foundcontract = $contract;
+											break;
+										}
+									}
+
+									dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__=' . $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__']);
+
+									//erics - erreur de réécriture de l'url de téléchargement direct de la facture ... le lien de base est le bon
+									//on cherche donc d'ou vien le pb ...
+									//$urlforsellyoursaasaccount = getRootUrlForAccount($foundcontract);
+									// if ($urlforsellyoursaasaccount) {
+									// 	$tmpforurl = preg_replace('/.*document.php/', '', $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__']);
+									// 	if ($tmpforurl) {
+									// 		dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__ cas 1, urlforsellyoursaasaccount=' . $urlforsellyoursaasaccount);
+									// 		// $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $urlforsellyoursaasaccount . '/source/document.php' . $tmpforurl;
+									// 	} else {
+									// 		dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__ cas 2, urlforsellyoursaasaccount=' . $urlforsellyoursaasaccount);
+									// 		// $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $urlforsellyoursaasaccount;
+									// 	}
+									// }
+
+									$subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
+									$texttosend = make_substitutions($msg, $substitutionarray, $outputlangs);
+
+									// Attach a file ?
+									$file = '';
+									$listofpaths = [];
+									$listofnames = [];
+									$listofmimes = [];
+									if (is_object($invoice)) {
+										$invoicediroutput = $conf->facture->dir_output;
+										//erics - choix du PDF a joindre aux mails
+										$fileparams = dol_most_recent_file($invoicediroutput . '/' . $this->ref, preg_quote($this->ref, '/') . '[^\-]+*.pdf');
+										$file = $fileparams['fullname'];
+										//$file = $invoicediroutput . '/' . $this->ref . '/' . $this->ref . '.pdf';
+										// $file = '';		// Disable attachment of invoice in emails
+
+										if ($file) {
+											$listofpaths = [$file];
+											$listofnames = [basename($file)];
+											$listofmimes = [dol_mimetype($file)];
+										}
+									}
+									$from = "";//$conf->global->SELLYOURSAAS_NOREPLY_EMAIL;
+
+									$trackid = 'inv' . $this->id;
+									$moreinheader = 'X-Dolibarr-Info: doTakeStripePaymentForThirdParty' . "\r\n";
+
+									// Send email (substitutionarray must be done just before this)
+									include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
+									$mailfile = new CMailFile($subjecttosend, $this->thirdparty->email, $from, $texttosend, $listofpaths, $listofmimes, $listofnames, '', '', 0, -1, '', '', $trackid, $moreinheader);
+									if ($mailfile->sendfile()) {
+										$result = 1;
+									} else {
+										$this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->thirdparty->email) . '. ' . $mailfile->error;
+										$result = -1;
+									}
+
+									if ($result < 0) {
+										$errmsg = $this->error;
+										$postactionmessages[] = $errmsg;
+										$ispostactionok = -1;
+									} else {
+										if ($file) {
+											$postactionmessages[] = 'Email sent to thirdparty (to ' . $this->thirdparty->email . ' with invoice document attached: ' . $file . ', language = ' . $outputlangs->defaultlang . ')';
+										} else {
+											$postactionmessages[] = 'Email sent to thirdparty (to ' . $this->thirdparty->email . ' without any attached document, language = ' . $outputlangs->defaultlang . ')';
+										}
+									}
+								}
+
+								if ($description) {
+									dol_syslog("* Record event for payment result - " . $description);
+									require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
+
+									// Insert record of payment (success or error)
+									$actioncomm = new ActionComm($this->db);
+
+									$actioncomm->type_code = 'AC_OTH_AUTO';		// Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
+									$actioncomm->code = 'AC_' . $actioncode;
+									$actioncomm->label = $description;
+									$actioncomm->note_private = join(",\n", $postactionmessages);
+									$actioncomm->fk_project = $this->fk_project;
+									$actioncomm->datep = $now;
+									$actioncomm->datef = $now;
+									$actioncomm->percentage = -1;   // Not applicable
+									$actioncomm->socid = $thirdparty->id;
+									$actioncomm->contactid = 0;
+									$actioncomm->authorid = $user->id;   // User saving action
+									$actioncomm->userownerid = $user->id;	// Owner of action
+									// Fields when action is a real email (content is already into note)
+									/*$actioncomm->email_msgid = $object->email_msgid;
+									 $actioncomm->email_from  = $object->email_from;
+									 $actioncomm->email_sender= $object->email_sender;
+									 $actioncomm->email_to    = $object->email_to;
+									 $actioncomm->email_tocc  = $object->email_tocc;
+									 $actioncomm->email_tobcc = $object->email_tobcc;
+									 $actioncomm->email_subject = $object->email_subject;
+									 $actioncomm->errors_to   = $object->errors_to;*/
+									$actioncomm->fk_element = $this->id;
+									$actioncomm->elementtype = $this->element;
+									$actioncomm->extraparams = dol_trunc($extraparams, 250);
+
+									$actioncomm->create($user);
+								}
+
+									$this->description = $description;
+									$this->postactionmessages = $postactionmessages;
+							} catch (Exception $e) {
+								$error++;
+								$errorforinvoice++;
+								dol_syslog('Error ' . $e->getMessage(), LOG_ERR);
+								$this->errors[] = 'Error ' . $e->getMessage();
+							}
+						} else {	// If remain to pay is null
+							$error++;
+							$errorforinvoice++;
+							dol_syslog("Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?", LOG_WARNING);
+							$this->errors[] = "Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?";
+						}
+
+							//end copy
+							// print json_encode($stripecard);
+							// exit;
+
+							$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande(';
+							$sql .= 'fk_facture, ';
+							$sql .= ' amount, date_demande, fk_user_demande, ext_payment_id, ext_payment_site, sourcetype, entity)';
+							$sql .= ' VALUES ('.$this->id;
+							$sql .= ",'".price2num($amount)."'";
+							$sql .= ",'".$this->db->idate($now)."'";
+							$sql .= ",".$fuser->id;
+							$sql .= ",'".$this->db->escape($stripe_id)."'";
+							$sql .= ",'".$this->db->escape($stripe_uri)."'";
+							$sql .= ",'".$this->db->escape($sourcetype)."'";
+							$sql .= ",".$conf->entity;
+							$sql .= ")";
+
+							dol_syslog(get_class($this)."::demande_prelevement_stripe", LOG_DEBUG);
+							$resql = $this->db->query($sql);
+						if (!$resql) {
+							$this->error = $this->db->lasterror();
+							dol_syslog(get_class($this).'::demande_prelevement_stripe Erreur');
+							$error++;
+						}
+					} else {
+						$this->error = 'WithdrawRequestErrorNilAmount';
+						dol_syslog(get_class($this).'::demande_prelevement_stripe WithdrawRequestErrorNilAmount');
+						$error++;
+					}
+
+					if (!$error) {
+						// Force payment mode of invoice to withdraw
+						$payment_mode_id = dol_getIdFromCode($this->db, ($type == 'bank-transfer' ? 'VIR' : 'PRE'), 'c_paiement', 'code', 'id', 1);
+						if ($payment_mode_id > 0) {
+							$result = $this->setPaymentMethods($payment_mode_id);
+						}
+					}
+
+					if ($error) {
+						return -1;
+					}
+						return 1;
+				} else {
+					$this->error = "A request already exists";
+					dol_syslog(get_class($this).'::demande_prelevement_stripe Impossible de creer une demande, demande deja en cours');
+					return 0;
+				}
+			} else {
+				$this->error = $this->db->error();
+				dol_syslog(get_class($this).'::demande_prelevement_stripe Erreur -2');
+				return -2;
+			}
+		} else {
+			$this->error = "Status of invoice does not allow this";
+			dol_syslog(get_class($this)."::demande_prelevement_stripe ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id");
+			return -3;
+		}
+	}
+
 	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
 	/**
 	 *  Remove a direct debit request or a credit transfer request

+ 1 - 0
htdocs/core/class/html.formticket.class.php

@@ -77,6 +77,7 @@ class FormTicket
 
 	public $withtitletopic;
 	public $withtopicreadonly;
+	public $withreadid;
 	public $withcompany; // affiche liste déroulante company
 	public $withfromsocid;
 	public $withfromcontactid;

+ 24 - 12
htdocs/core/class/utils.class.php

@@ -52,8 +52,8 @@ class Utils
 	 *  Purge files into directory of data files.
 	 *  CAN BE A CRON TASK
 	 *
-	 *  @param	string      $choices	   Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than $nbsecondsold seconds, 'logfiles', or mix of this). Note 'allfiles' is possible too but very dangerous.
-	 *  @param  int         $nbsecondsold  Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold'
+	 *  @param	string      $choices	   Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than $nbsecondsold seconds, 'logfiles', or mix of this). Note that 'allfiles' is also possible but very dangerous.
+	 *  @param  int         $nbsecondsold  Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold', or deletion of file if $choice is 'allfiles'
 	 *  @return	int						   0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
 	 */
 	public function purgeFiles($choices = 'tempfilesold+logfiles', $nbsecondsold = 86400)
@@ -67,6 +67,9 @@ class Utils
 		if (empty($choices)) {
 			$choices = 'tempfilesold+logfiles';
 		}
+		if ($choices == 'allfiles' && $nbsecondsold > 0) {
+			$choices = 'allfilesold';
+		}
 
 		dol_syslog("Utils::purgeFiles choice=".$choices, LOG_DEBUG);
 
@@ -77,6 +80,7 @@ class Utils
 
 		$choicesarray = preg_split('/[\+,]/', $choices);
 		foreach ($choicesarray as $choice) {
+			$now = dol_now();
 			$filesarray = array();
 
 			if ($choice == 'tempfiles' || $choice == 'tempfilesold') {
@@ -85,7 +89,6 @@ class Utils
 					$filesarray = dol_dir_list($dolibarr_main_data_root, "directories", 1, '^temp$', '', 'name', SORT_ASC, 2, 0, '', 1); // Do not follow symlinks
 
 					if ($choice == 'tempfilesold') {
-						$now = dol_now();
 						foreach ($filesarray as $key => $val) {
 							if ($val['date'] > ($now - ($nbsecondsold))) {
 								unset($filesarray[$key]); // Discard temp dir not older than $nbsecondsold
@@ -98,7 +101,14 @@ class Utils
 			if ($choice == 'allfiles') {
 				// Delete all files (except install.lock, do not follow symbolic links)
 				if ($dolibarr_main_data_root) {
-					$filesarray = dol_dir_list($dolibarr_main_data_root, "all", 0, '', 'install\.lock$', 'name', SORT_ASC, 0, 0, '', 1);
+					$filesarray = dol_dir_list($dolibarr_main_data_root, "all", 0, '', 'install\.lock$', 'name', SORT_ASC, 0, 0, '', 1);	// No need to use recursive, we will delete directory
+				}
+			}
+
+			if ($choice == 'allfilesold') {
+				// Delete all files (except install.lock, do not follow symbolic links)
+				if ($dolibarr_main_data_root) {
+					$filesarray = dol_dir_list($dolibarr_main_data_root, "files", 1, '', 'install\.lock$', 'name', SORT_ASC, 0, 0, '', 1, $nbsecondsold);	// No need to use recursive, we will delete directory
 				}
 			}
 
@@ -138,14 +148,16 @@ class Utils
 							$countdeleted += $tmpcountdeleted;
 						}
 					} elseif ($filesarray[$key]['type'] == 'file') {
-						// If (file that is not logfile) or (if mode is logfile)
-						if ($filesarray[$key]['fullname'] != $filelog || $choice == 'logfile' || $choice == 'logfiles') {
-							$result = dol_delete_file($filesarray[$key]['fullname'], 1, 1);
-							if ($result) {
-								$count++;
-								$countdeleted++;
-							} else {
-								$counterror++;
+						if ($choice != 'allfilesold' || $filesarray[$key]['date'] < ($now - $nbsecondsold)) {
+							// If (file that is not logfile) or (if mode is logfile)
+							if ($filesarray[$key]['fullname'] != $filelog || $choice == 'logfile' || $choice == 'logfiles') {
+								$result = dol_delete_file($filesarray[$key]['fullname'], 1, 1);
+								if ($result) {
+									$count++;
+									$countdeleted++;
+								} else {
+									$counterror++;
+								}
 							}
 						}
 					}

+ 1 - 1
htdocs/core/db/mysqli.class.php

@@ -421,7 +421,7 @@ class DoliDBMysqli extends DoliDB
 		if (!is_object($resultset)) {
 			$resultset = $this->_results;
 		}
-		return $resultset->num_rows;
+		return isset($resultset->num_rows) ? $resultset->num_rows : 0;
 	}
 
 	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps

+ 21 - 17
htdocs/core/lib/files.lib.php

@@ -54,10 +54,11 @@ function dol_basename($pathfile)
  *  @param	int			$nohook			Disable all hooks
  *  @param	string		$relativename	For recursive purpose only. Must be "" at first call.
  *  @param	string		$donotfollowsymlinks	Do not follow symbolic links
+ *  @param	string		$nbsecondsold	Only files older than $nbsecondsold
  *  @return	array						Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file',...)
  *  @see dol_dir_list_in_database()
  */
-function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0, $nohook = 0, $relativename = "", $donotfollowsymlinks = 0)
+function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0, $nohook = 0, $relativename = "", $donotfollowsymlinks = 0, $nbsecondsold = 0)
 {
 	global $db, $hookmanager;
 	global $object;
@@ -67,13 +68,14 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl
 		//print 'xxx'."files.lib.php::dol_dir_list path=".$path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter);
 	}
 
-	$loaddate = ($mode == 1 || $mode == 2) ?true:false;
-	$loadsize = ($mode == 1 || $mode == 3) ?true:false;
-	$loadperm = ($mode == 1 || $mode == 4) ?true:false;
+	$loaddate = ($mode == 1 || $mode == 2 || $nbsecondsold) ? true : false;
+	$loadsize = ($mode == 1 || $mode == 3) ?true : false;
+	$loadperm = ($mode == 1 || $mode == 4) ?true : false;
 
 	// Clean parameters
 	$path = preg_replace('/([\\/]+)$/i', '', $path);
 	$newpath = dol_osencode($path);
+	$now = dol_now();
 
 	$reshook = 0;
 	$file_list = array();
@@ -170,7 +172,7 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl
 						if ($recursive > 0) {
 							if (empty($donotfollowsymlinks) || !is_link($path."/".$file)) {
 								//var_dump('eee '. $path."/".$file. ' '.is_dir($path."/".$file).' '.is_link($path."/".$file));
-								$file_list = array_merge($file_list, dol_dir_list($path."/".$file, $types, $recursive + 1, $filter, $excludefilter, $sortcriteria, $sortorder, $mode, $nohook, ($relativename != '' ? $relativename.'/' : '').$file, $donotfollowsymlinks));
+								$file_list = array_merge($file_list, dol_dir_list($path."/".$file, $types, $recursive + 1, $filter, $excludefilter, $sortcriteria, $sortorder, $mode, $nohook, ($relativename != '' ? $relativename.'/' : '').$file, $donotfollowsymlinks, $nbsecondsold));
 							}
 						}
 					} elseif (!$isdir && (($types == "files") || ($types == "all"))) {
@@ -183,18 +185,20 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl
 						}
 
 						if (!$filter || preg_match('/'.$filter.'/i', $file)) {	// We do not search key $filter into $path, only into $file
-							preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg);
-							$level1name = (isset($reg[1]) ? $reg[1] : '');
-							$file_list[] = array(
-								"name" => $file,
-								"path" => $path,
-								"level1name" => $level1name,
-								"relativename" => ($relativename ? $relativename.'/' : '').$file,
-								"fullname" => $path.'/'.$file,
-								"date" => $filedate,
-								"size" => $filesize,
-								"type" => 'file'
-							);
+							if (empty($nbsecondsold) || $filedate <= ($now - $nbsecondsold)) {
+								preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg);
+								$level1name = (isset($reg[1]) ? $reg[1] : '');
+								$file_list[] = array(
+									"name" => $file,
+									"path" => $path,
+									"level1name" => $level1name,
+									"relativename" => ($relativename ? $relativename.'/' : '').$file,
+									"fullname" => $path.'/'.$file,
+									"date" => $filedate,
+									"size" => $filesize,
+									"type" => 'file'
+								);
+							}
 						}
 					}
 				}

+ 2 - 1
htdocs/core/lib/functions.lib.php

@@ -4955,8 +4955,9 @@ function dol_print_error($db = '', $error = '', $errors = null)
 		$out .= "<br>\n";
 	}
 
-	// Return a http error code if possible
+	// Return a http header with error code if possible
 	if (!headers_sent()) {
+		top_httphead();
 		http_response_code(500);
 	}
 

+ 35 - 5
htdocs/core/lib/security.lib.php

@@ -329,11 +329,11 @@ function dolGetLdapPasswordHash($password, $type = 'md5')
  *  @param  string		$dbt_keyfield   Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
  *  @param  string		$dbt_select     Field name for select if not rowid. Not used if objectid is null (optional)
  *  @param	int			$isdraft		1=The object with id=$objectid is a draft
- *  @param	int			$mode			Mode (0=default, 1=return with not die)
+ *  @param	int			$mode			Mode (0=default, 1=return without dieing)
  * 	@return	int							If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed.
  *  @see dol_check_secure_access_document(), checkUserAccessToObject()
  */
-function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
+function restrictedArea(User $user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
 {
 	global $db, $conf;
 	global $hookmanager;
@@ -1016,8 +1016,35 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
 	return true;
 }
 
+
 /**
- *	Show a message to say access is forbidden and stop program
+ *	Show a message to say access is forbidden and stop program.
+ *  This includes only HTTP header.
+ *	Calling this function terminate execution of PHP.
+ *
+ *	@param	string		$message					Force error message
+ *	@param	int			$http_response_code			HTTP response code
+ *  @param	int			$stringalreadysanitized		1 if string is already sanitized with HTML entities
+ *  @return	void
+ *  @see accessforbidden()
+ */
+function httponly_accessforbidden($message = 1, $http_response_code = 403, $stringalreadysanitized = 0)
+{
+	top_httphead();
+	http_response_code($http_response_code);
+
+	if ($stringalreadysanitized) {
+		print $message;
+	} else {
+		print htmlentities($message);
+	}
+
+	exit(1);
+}
+
+/**
+ *	Show a message to say access is forbidden and stop program.
+ *  This includes HTTP and HTML header and footer (except if $printheader and $printfooter is  0, use this case inside an already started page).
  *	Calling this function terminate execution of PHP.
  *
  *	@param	string		$message			Force error message
@@ -1026,10 +1053,12 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
  *  @param  int			$showonlymessage    Show only message parameter. Otherwise add more information.
  *  @param  array|null  $params         	More parameters provided to hook
  *  @return	void
+ *  @see httponly_accessforbidden()
  */
 function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $showonlymessage = 0, $params = null)
 {
 	global $conf, $db, $user, $langs, $hookmanager;
+
 	if (!is_object($langs)) {
 		include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
 		$langs = new Translate('', $conf);
@@ -1046,10 +1075,10 @@ function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $sho
 		}
 	}
 	print '<div class="error">';
-	if (!$message) {
+	if (empty($message)) {
 		print $langs->trans("ErrorForbidden");
 	} else {
-		print $message;
+		print $langs->trans($message);
 	}
 	print '</div>';
 	print '<br>';
@@ -1077,6 +1106,7 @@ function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $sho
 	if ($printfooter && function_exists("llxFooter")) {
 		llxFooter();
 	}
+
 	exit(0);
 }
 

+ 2 - 2
htdocs/core/modules/commande/mod_commande_saphir.php

@@ -79,7 +79,7 @@ class mod_commande_saphir extends ModeleNumRefCommandes
 
 		// Parametrage du prefix
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskorder" value="'.$conf->global->COMMANDE_SAPHIR_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskorder" value="'.getDolGlobalString("COMMANDE_SAPHIR_MASK").'">', $tooltip, 1, 1).'</td>';
 
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button"value="'.$langs->trans("Modify").'"></td>';
 
@@ -128,7 +128,7 @@ class mod_commande_saphir extends ModeleNumRefCommandes
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
 		// We get cursor rule
-		$mask = $conf->global->COMMANDE_SAPHIR_MASK;
+		$mask = getDolGlobalString("COMMANDE_SAPHIR_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 2 - 2
htdocs/core/modules/contract/mod_contract_magre.php

@@ -85,7 +85,7 @@ class mod_contract_magre extends ModelNumRefContracts
 		$tooltip .= $langs->trans("GenericMaskCodes5");
 
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskcontract" value="'.$conf->global->CONTRACT_MAGRE_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskcontract" value="'.getDolGlobalString("CONTRACT_MAGRE_MASK").'">', $tooltip, 1, 1).'</td>';
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button"value="'.$langs->trans("Modify").'"></td>';
 		$texte .= '</tr>';
 		$texte .= '</table>';
@@ -127,7 +127,7 @@ class mod_contract_magre extends ModelNumRefContracts
 
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
-		$mask = $conf->global->CONTRACT_MAGRE_MASK;
+		$mask = getDolGlobalString("CONTRACT_MAGRE_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 2 - 2
htdocs/core/modules/fichinter/mod_arctic.php

@@ -84,7 +84,7 @@ class mod_arctic extends ModeleNumRefFicheinter
 
 		// Setting the prefix
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskvalue" value="'.$conf->global->FICHINTER_ARTIC_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskvalue" value="'.getDolGlobalString("FICHINTER_ARTIC_MASK").'">', $tooltip, 1, 1).'</td>';
 
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button" value="'.$langs->trans("Modify").'"></td>';
 
@@ -130,7 +130,7 @@ class mod_arctic extends ModeleNumRefFicheinter
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
 		// We define the search criteria of the counter
-		$mask = $conf->global->FICHINTER_ARTIC_MASK;
+		$mask = getDolGlobalString("FICHINTER_ARTIC_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 3 - 1
htdocs/core/modules/modZapier.class.php

@@ -15,6 +15,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
+
 /**
  *  \defgroup   zapier     Module Zapier
  *  \brief      Zapier module descriptor.
@@ -23,7 +24,8 @@
  *  \ingroup    zapier
  *  \brief      Description and activation file for the module Zapier
  */
-include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
+
+require_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
 
 /**
  *  Description and activation class for module Zapier

+ 2 - 2
htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php

@@ -123,7 +123,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
 		$texte .= '<input type="hidden" name="page_y" value="">';
 		$texte .= '<input type="hidden" name="action" value="setModuleOptions">';
 		$texte .= '<input type="hidden" name="param1" value="PROPALE_ADDON_PDF_ODT_PATH">';
-		if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) {
+		if (getDolGlobalInt("MAIN_PROPAL_CHOOSE_ODT_DOCUMENT") > 0) {
 			$texte .= '<input type="hidden" name="param2" value="PROPALE_ADDON_PDF_ODT_DEFAULT">';
 			$texte .= '<input type="hidden" name="param3" value="PROPALE_ADDON_PDF_ODT_TOBILL">';
 			$texte .= '<input type="hidden" name="param4" value="PROPALE_ADDON_PDF_ODT_CLOSED">';
@@ -187,7 +187,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
 			$texte .= '</div>';
 
 			// Set default template for different status of proposal
-			if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) {
+			if (getDolGlobalInt("MAIN_PROPAL_CHOOSE_ODT_DOCUMENT") > 0) {
 				// Model for creation
 				$list = ModelePDFPropales::liste_modeles($this->db);
 				$texte .= '<table width="50%;">';

+ 2 - 2
htdocs/core/modules/reception/mod_reception_moonstone.php

@@ -61,7 +61,7 @@ class mod_reception_moonstone extends ModelNumRefReception
 		$tooltip .= $langs->trans("GenericMaskCodes5");
 
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskreception" value="'.$conf->global->RECEPTION_MOONSTONE_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskreception" value="'.getDolGlobalString("RECEPTION_MOONSTONE_MASK").'">', $tooltip, 1, 1).'</td>';
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button" value="'.$langs->trans("Modify").'"></td>';
 		$texte .= '</tr>';
 		$texte .= '</table>';
@@ -106,7 +106,7 @@ class mod_reception_moonstone extends ModelNumRefReception
 
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
-		$mask = $conf->global->RECEPTION_MOONSTONE_MASK;
+		$mask = getDolGlobalString("RECEPTION_MOONSTONE_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 11 - 11
htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php

@@ -67,12 +67,12 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
 	 */
 	public function info()
 	{
-		global $conf, $langs;
+		global $conf, $langs, $db;
 
 		// Load translation files required by the page
 		$langs->loadLangs(array("bills", "admin"));
 
-		$form = new Form($this->db);
+		$form = new Form($db);
 
 		$texte = $langs->trans('GenericNumRefModelDesc')."<br>\n";
 		$texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
@@ -93,7 +93,7 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
 		// Setting the prefix
 		$texte .= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceStandard").')';
 		$texte .= ':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskinvoice" value="'.$conf->global->SUPPLIER_INVOICE_TULIP_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskinvoice" value="'.getDolGlobalString("SUPPLIER_INVOICE_TULIP_MASK").'">', $tooltip, 1, 1).'</td>';
 
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button"value="'.$langs->trans("Modify").'"></td>';
 
@@ -101,19 +101,19 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
 
 		// Prefix setting of credit note
 		$texte .= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'):</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskcredit" value="'.$conf->global->SUPPLIER_CREDIT_TULIP_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskcredit" value="'.getDolGlobalString("SUPPLIER_CREDIT_TULIP_MASK").'">', $tooltip, 1, 1).'</td>';
 		$texte .= '</tr>';
 
 		if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
 			// Parametrage du prefix des replacement
 			$texte .= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceReplacement").'):</td>';
-			$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskreplacement" value="'.$conf->global->SUPPLIER_REPLACEMENT_TULIP_MASK.'">', $tooltip, 1, 1).'</td>';
+			$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskreplacement" value="'.getDolGlobalString("SUPPLIER_REPLACEMENT_TULIP_MASK").'">', $tooltip, 1, 1).'</td>';
 			$texte .= '</tr>';
 		}
 
 		// Prefix setting of deposit
 		$texte .= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceDeposit").'):</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskdeposit" value="'.$conf->global->SUPPLIER_DEPOSIT_TULIP_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskdeposit" value="'.getDolGlobalString("SUPPLIER_DEPOSIT_TULIP_MASK").'">', $tooltip, 1, 1).'</td>';
 		$texte .= '</tr>';
 
 		$texte .= '</table>';
@@ -159,16 +159,16 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
 		// Get Mask value
 		$mask = '';
 		if (is_object($object) && $object->type == 1) {
-			$mask = $conf->global->SUPPLIER_REPLACEMENT_TULIP_MASK;
+			$mask = getDolGlobalString("SUPPLIER_REPLACEMENT_TULIP_MASK");
 			if (!$mask) {
-				$mask = $conf->global->SUPPLIER_INVOICE_TULIP_MASK;
+				$mask = getDolGlobalString("SUPPLIER_INVOICE_TULIP_MASK");
 			}
 		} elseif (is_object($object) && $object->type == 2) {
-			$mask = $conf->global->SUPPLIER_CREDIT_TULIP_MASK;
+			$mask = getDolGlobalString("SUPPLIER_CREDIT_TULIP_MASK");
 		} elseif (is_object($object) && $object->type == 3) {
-			$mask = $conf->global->SUPPLIER_DEPOSIT_TULIP_MASK;
+			$mask = getDolGlobalString("SUPPLIER_DEPOSIT_TULIP_MASK");
 		} else {
-			$mask = $conf->global->SUPPLIER_INVOICE_TULIP_MASK;
+			$mask = getDolGlobalString("SUPPLIER_INVOICE_TULIP_MASK");
 		}
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 2 - 2
htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php

@@ -85,7 +85,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
 
 		// Parametrage du prefix
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskorder" value="'.$conf->global->COMMANDE_FOURNISSEUR_ORCHIDEE_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskorder" value="'.getDolGlobalString("COMMANDE_FOURNISSEUR_ORCHIDEE_MASK").'">', $tooltip, 1, 1).'</td>';
 
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button"value="'.$langs->trans("Modify").'"></td>';
 
@@ -131,7 +131,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
 		// On defini critere recherche compteur
-		$mask = $conf->global->COMMANDE_FOURNISSEUR_ORCHIDEE_MASK;
+		$mask = getDolGlobalString("COMMANDE_FOURNISSEUR_ORCHIDEE_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 4 - 4
htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php

@@ -61,11 +61,11 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
 	 */
 	public function info()
 	{
-		global $conf, $langs;
+		global $conf, $langs, $db;
 
 		$langs->load("bills");
 
-		$form = new Form($this->db);
+		$form = new Form($db);
 
 		$texte = $langs->trans('GenericNumRefModelDesc')."<br>\n";
 		$texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
@@ -82,7 +82,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
 
 		// Parametrage du prefix
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="masksupplierpayment" value="'.$conf->global->SUPPLIER_PAYMENT_BRODATOR_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="masksupplierpayment" value="'.getDolGlobalString("SUPPLIER_PAYMENT_BRODATOR_MASK").'">', $tooltip, 1, 1).'</td>';
 
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button"value="'.$langs->trans("Modify").'"></td>';
 
@@ -128,7 +128,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
 		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
 		// We get cursor rule
-		$mask = $conf->global->SUPPLIER_PAYMENT_BRODATOR_MASK;
+		$mask = getDolGlobalString("SUPPLIER_PAYMENT_BRODATOR_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 3 - 3
htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php

@@ -1323,7 +1323,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
 				}
 			} else {
 				$text = $this->emetteur->name;
-				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
+				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0);
 			}
 		}
 
@@ -1343,11 +1343,11 @@ class pdf_aurore extends ModelePDFSupplierProposal
 		$posy += 1;
 		$pdf->SetFont('', '', $default_font_size - 2);
 
-		if ($object->ref_client) {
+		if ($object->ref_fourn) {
 			$posy += 4;
 			$pdf->SetXY($posx, $posy);
 			$pdf->SetTextColor(0, 0, 60);
-			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_client), 65), '', 'R');
+			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefSupplier")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_fourn), 65), '', 'R');
 		}
 		/* PHFAVRE
 		$posy+=4;

+ 2 - 2
htdocs/core/modules/ticket/mod_ticket_universal.php

@@ -81,7 +81,7 @@ class mod_ticket_universal extends ModeleNumRefTicket
 
 		// Parametrage du prefix
 		$texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskticket" value="'.$conf->global->TICKET_UNIVERSAL_MASK.'">', $tooltip, 1, 1).'</td>';
+		$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskticket" value="'.getDolGlobalString("TICKET_UNIVERSAL_MASK").'">', $tooltip, 1, 1).'</td>';
 
 		$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" name="Button"value="'.$langs->trans("Modify").'"></td>';
 
@@ -127,7 +127,7 @@ class mod_ticket_universal extends ModeleNumRefTicket
 		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 
 		// On defini critere recherche compteur
-		$mask = $conf->global->TICKET_UNIVERSAL_MASK;
+		$mask = getDolGlobalString("TICKET_UNIVERSAL_MASK");
 
 		if (!$mask) {
 			$this->error = 'NotConfigured';

+ 1 - 3
htdocs/core/tpl/login.tpl.php

@@ -33,10 +33,8 @@ if (empty($conf) || !is_object($conf)) {
 // DDOS protection
 $size = (empty($_SERVER['CONTENT_LENGTH']) ? 0 : (int) $_SERVER['CONTENT_LENGTH']);
 if ($size > 10000) {
-	http_response_code(413);
 	$langs->loadLangs(array("errors", "install"));
-	accessforbidden('<center>'.$langs->trans("ErrorRequestTooLarge").'.<br><a href="'.DOL_URL_ROOT.'">'.$langs->trans("ClickHereToGoToApp").'</a></center>', 0, 0, 1);
-	exit;
+	httponly_accessforbidden('<center>'.$langs->trans("ErrorRequestTooLarge").'.<br><a href="'.DOL_URL_ROOT.'">'.$langs->trans("ClickHereToGoToApp").'</a></center>', 413, 1);
 }
 
 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';

+ 1 - 3
htdocs/core/tpl/passwordforgotten.tpl.php

@@ -30,10 +30,8 @@ if (empty($conf) || !is_object($conf)) {
 // DDOS protection
 $size = (int) $_SERVER['CONTENT_LENGTH'];
 if ($size > 10000) {
-	http_response_code(413);
 	$langs->loadLangs(array("errors", "install"));
-	accessforbidden('<center>'.$langs->trans("ErrorRequestTooLarge").'<br><a href="'.DOL_URL_ROOT.'">'.$langs->trans("ClickHereToGoToApp").'</a></center>', 0, 0, 1);
-	exit;
+	httponly_accessforbidden('<center>'.$langs->trans("ErrorRequestTooLarge").'<br><a href="'.DOL_URL_ROOT.'">'.$langs->trans("ClickHereToGoToApp").'</a></center>', 413, 1);
 }
 
 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';

+ 25 - 1
htdocs/core/website.inc.php

@@ -75,6 +75,18 @@ if ($pageid > 0) {
 
 	if (!defined('USEDOLIBARREDITOR') && (in_array($websitepage->type_container, array('menu', 'other')) || empty($websitepage->status) && !defined('USEDOLIBARRSERVER'))) {
 		$weblangs->load("website");
+
+		// Security options
+
+		// X-Content-Type-Options
+		header("X-Content-Type-Options: nosniff");
+
+		// X-Frame-Options
+		if (empty($websitepage->allowed_in_frames) && empty($conf->global->WEBSITE_ALLOW_FRAMES_ON_ALL_PAGES)) {
+			header("X-Frame-Options: SAMEORIGIN");
+		}
+
+		//httponly_accessforbidden('<center><br><br>'.$weblangs->trans("YouTryToAccessToAFileThatIsNotAWebsitePage", $websitepage->pageurl, $websitepage->type_container, $websitepage->status).'</center>', 404, 1);
 		http_response_code(404);
 		print '<center><br><br>'.$weblangs->trans("YouTryToAccessToAFileThatIsNotAWebsitePage", $websitepage->pageurl, $websitepage->type_container, $websitepage->status).'</center>';
 		exit;
@@ -198,9 +210,21 @@ if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php') {	// If we browsi
 	}
 }
 
-// Show off line message
+// Show off line message when all website is off
 if (!defined('USEDOLIBARREDITOR') && empty($website->status)) {
+	// Security options
+
+	// X-Content-Type-Options
+	header("X-Content-Type-Options: nosniff");
+
+	// X-Frame-Options
+	if (empty($websitepage->allowed_in_frames) && empty($conf->global->WEBSITE_ALLOW_FRAMES_ON_ALL_PAGES)) {
+		header("X-Frame-Options: SAMEORIGIN");
+	}
+
 	$weblangs->load("website");
+
+	//httponly_accessforbidden('<center><br><br>'.$weblangs->trans("SorryWebsiteIsCurrentlyOffLine").'</center>', 503, 1);
 	http_response_code(503);
 	print '<center><br><br>'.$weblangs->trans("SorryWebsiteIsCurrentlyOffLine").'</center>';
 	exit;

+ 4 - 4
htdocs/document.php

@@ -104,10 +104,10 @@ $entity = GETPOST('entity', 'int') ?GETPOST('entity', 'int') : $conf->entity;
 
 // Security check
 if (empty($modulepart) && empty($hashp)) {
-	accessforbidden('Bad link. Bad value for parameter modulepart', 0, 0, 1);
+	httponly_accessforbidden('Bad link. Bad value for parameter modulepart', 400);
 }
 if (empty($original_file) && empty($hashp)) {
-	accessforbidden('Bad link. Missing identification to find file (original_file or hashp)', 0, 0, 1);
+	httponly_accessforbidden('Bad link. Missing identification to find file (original_file or hashp)', 400);
 }
 if ($modulepart == 'fckeditor') {
 	$modulepart = 'medias'; // For backward compatibility
@@ -158,7 +158,7 @@ if (!empty($hashp)) {
 				$original_file = (($tmp[1] ? $tmp[1].'/' : '').$ecmfile->filename); // this is relative to module dir
 				//var_dump($original_file); exit;
 			} else {
-				accessforbidden('Bad link. File is from another module part.', 0, 0, 1);
+				httponly_accessforbidden('Bad link. File is from another module part.', 403);
 			}
 		} else {
 			$modulepart = $moduleparttocheck;
@@ -171,7 +171,7 @@ if (!empty($hashp)) {
 		}
 	} else {
 		$langs->load("errors");
-		accessforbidden($langs->trans("ErrorFileNotFoundWithSharedLink"), 0, 0, 1);
+		httponly_accessforbidden($langs->trans("ErrorFileNotFoundWithSharedLink"), 403, 1);
 	}
 }
 

+ 0 - 1
htdocs/eventorganization/conferenceorboothattendee_note.php

@@ -38,7 +38,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification
 

+ 38 - 1
htdocs/fourn/commande/list.php

@@ -189,7 +189,9 @@ $arrayfields = array(
 	'state.nom'=>array('label'=>"StateShort", 'enabled'=>1, 'position'=>48),
 	'country.code_iso'=>array('label'=>"Country", 'enabled'=>1, 'position'=>49),
 	'typent.code'=>array('label'=>"ThirdPartyType", 'enabled'=>$checkedtypetiers, 'position'=>50),
-	'u.login'=>array('label'=>"AuthorRequest", 'enabled'=>1, 'position'=>51)
+	'u.login'=>array('label'=>"AuthorRequest", 'enabled'=>1, 'position'=>51),
+	'cf.note_public'=>array('label'=>'NotePublic', 'checked'=>0, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PUBLIC_NOTES)), 'position'=>100),
+	'cf.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PRIVATE_NOTES)), 'position'=>110),
 );
 foreach ($object->fields as $key => $val) {
 	// If $val['visible']==0, then we never show the field
@@ -1441,6 +1443,16 @@ if ($resql) {
 		print '</div>';
 		print '</td>';
 	}
+	// Note public
+	if (!empty($arrayfields['cf.note_public']['checked'])) {
+		print '<td class="liste_titre">';
+		print '</td>';
+	}
+	// Note private
+	if (!empty($arrayfields['cf.note_private']['checked'])) {
+		print '<td class="liste_titre">';
+		print '</td>';
+	}
 	// Action column
 	print '<td class="liste_titre middle">';
 	$searchpicto = $form->showFilterButtons();
@@ -1541,6 +1553,12 @@ if ($resql) {
 	if (!empty($arrayfields['cf.date_approve']['checked'])) {
 		print_liste_field_titre($arrayfields['cf.date_approve']['label'], $_SERVER["PHP_SELF"], 'cf.date_approve', '', $param, '', $sortfield, $sortorder, 'center ');
 	}
+	if (!empty($arrayfields['cf.note_public']['checked'])) {
+		print_liste_field_titre($arrayfields['cf.note_public']['label'], $_SERVER["PHP_SELF"], "cf.note_public", "", $param, '', $sortfield, $sortorder, 'center ');
+	}
+	if (!empty($arrayfields['cf.note_private']['checked'])) {
+		print_liste_field_titre($arrayfields['cf.note_private']['label'], $_SERVER["PHP_SELF"], "cf.note_private", "", $param, '', $sortfield, $sortorder, 'center ');
+	}
 	print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
 	print "</tr>\n";
 
@@ -1868,6 +1886,25 @@ if ($resql) {
 				$totalarray['nbfield']++;
 			}
 		}
+		// Note public
+		if (!empty($arrayfields['cf.note_public']['checked'])) {
+			print '<td class="center">';
+			print dol_string_nohtmltag($obj->note_public);
+			print '</td>';
+			if (!$i) {
+				$totalarray['nbfield']++;
+			}
+		}
+
+		// Note private
+		if (!empty($arrayfields['cf.note_private']['checked'])) {
+			print '<td class="center">';
+			print dol_string_nohtmltag($obj->note_private);
+			print '</td>';
+			if (!$i) {
+				$totalarray['nbfield']++;
+			}
+		}
 
 		// Action column
 		print '<td class="nowrap center">';

+ 1 - 1
htdocs/hrm/admin/admin_establishment.php

@@ -53,10 +53,10 @@ if (empty($page) || $page == -1) {
 	$page = 0;
 }
 
+$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
 $offset = $limit * $page;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
-$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
 
 
 /*

+ 1 - 1
htdocs/hrm/establishment/card.php

@@ -255,7 +255,7 @@ if ($action == 'create') {
 }
 
 // Part to edit record
-if (($id || $ref) && $action == 'edit') {
+if ((!empty($id) || !empty($ref)) && $action == 'edit') {
 	$result = $object->fetch($id);
 	if ($result > 0) {
 		$head = establishment_prepare_head($object);

+ 0 - 1
htdocs/hrm/position.php

@@ -41,7 +41,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification
 

+ 7 - 6
htdocs/hrm/skill_card.php

@@ -47,7 +47,7 @@ $cancel = GETPOST('cancel', 'aZ09');
 $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'skillcard'; // To manage different context of search
 $backtopage = GETPOST('backtopage', 'alpha');
 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
-//$lineid   = GETPOST('lineid', 'int');
+$lineid   = GETPOST('lineid', 'int');
 
 // Initialize technical objects
 $object = new Skill($db);
@@ -577,7 +577,7 @@ if ($action != "create" && $action != "edit") {
 	$title = $langs->transnoentitiesnoconv("Skilldets");
 	$morejs = array();
 	$morecss = array();
-
+	$nbtotalofrecords = 0;
 
 	// Build and execute select
 	// --------------------------------------------------------------------
@@ -626,8 +626,10 @@ if ($action != "create" && $action != "edit") {
 		print '<input type="hidden" name="id" value="' . $id . '">';
 	}
 
-	$param_fk = "&fk_skill=" . $id . "&fk_user_creat=" . $user->rowid;
+	$param_fk = "&fk_skill=" . $id . "&fk_user_creat=" . (!empty($user->rowid) ? $user->rowid :0);
 	$backtopage = dol_buildpath('/hrm/skill_card.php', 1) . '?id=' . $id;
+	$param = "";
+	$massactionbutton = "";
 	//$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/skilldet_card.php', 1) . '?action=create&backtopage=' . urlencode($_SERVER['PHP_SELF']) . $param_fk . '&backtopage=' . $backtopage, '', $permissiontoadd);
 
 	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_' . $object->picto, 0, "", '', '', 0, 0, 1);
@@ -688,7 +690,7 @@ if ($action != "create" && $action != "edit") {
 		//          $cssforfield .= ($cssforfield ? ' ' : '') . 'right';
 		//      }
 		if (!empty($arrayfields['t.' . $key]['checked'])) {
-			print getTitleFieldOfList($arrayfields['t.' . $key]['label'], 0, $_SERVER['PHP_SELF'], 't.' . $key, '', $param, ($cssforfield ? 'class="' . $cssforfield . '"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield . ' ' : '')) . "\n";
+			print getTitleFieldOfList($arrayfields['t.' . $key]['label'], 0, $_SERVER['PHP_SELF'], 't.' . $key, '', $param, (!empty($cssforfield) ? 'class="' . $cssforfield . '"' : ''), $sortfield, $sortorder, (!empty($cssforfield) ? $cssforfield . ' ' : '')) . "\n";
 		}
 	}
 	print '<td></td>';
@@ -814,8 +816,7 @@ if ($action != "create" && $action != "edit") {
 		print '<tr><td colspan="' . $colspan . '" class="opacitymedium">' . $langs->trans("NoRecordFound") . '</td></tr>';
 	}
 
-
-	$db->free($resql);
+	if (!empty($resql)) $db->free($resql);
 
 	$parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
 	$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $objectline); // Note that $action and $objectline may have been modified by hook

+ 3 - 1
htdocs/hrm/skill_tab.php

@@ -64,7 +64,9 @@ if (in_array($objecttype, $TAuthorizedObjects)) {
 	} elseif ($objecttype == "user") {
 		$object = new User($db);
 	}
-} else accessforbidden($langs->trans('ErrorBadObjectType'));
+} else {
+	accessforbidden('ErrorBadObjectType');
+}
 
 $hookmanager->initHooks(array('skilltab', 'globalcard')); // Note that conf->hooks_modules contains array
 

+ 2 - 1
htdocs/langs/en_US/errors.lang

@@ -292,7 +292,8 @@ ErrorThirpdartyOrMemberidIsMandatory=Third party or Member of partnership is man
 ErrorFailedToWriteInTempDirectory=Failed to write in temp directory
 ErrorQuantityIsLimitedTo=Quantity is limited to %s
 ErrorFailedToLoadThirdParty=Failed to find/load thirdparty from id=%s, email=%s, name=%s
- 
+ErrorThisPaymentModeIsNotSepa=This payment mode is not a bank account 
+
 # Warnings
 WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
 WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.

+ 8 - 5
htdocs/main.inc.php

@@ -547,12 +547,12 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && getDolGlobalInt(
 	) {
 		// If token is not provided or empty, error (we are in case it is mandatory)
 		if (!GETPOST('token', 'alpha') || GETPOST('token', 'alpha') == 'notrequired') {
+			top_httphead();
 			if (GETPOST('uploadform', 'int')) {
 				dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused. File size too large or not provided.");
 				$langs->loadLangs(array("errors", "install"));
 				print $langs->trans("ErrorFileSizeTooLarge").' ';
 				print $langs->trans("ErrorGoBackAndCorrectParameters");
-				die;
 			} else {
 				http_response_code(403);
 				if (defined('CSRFCHECK_WITH_TOKEN')) {
@@ -567,8 +567,8 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && getDolGlobalInt(
 					}
 					print " into setup).\n";
 				}
-				die;
 			}
+			die;
 		}
 	}
 
@@ -851,12 +851,16 @@ if (!defined('NOLOGIN')) {
 			// No data to test login, so we show the login page.
 			dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." - action=".GETPOST('action', 'aZ09')." - actionlogin=".GETPOST('actionlogin', 'aZ09')." - showing the login form and exit", LOG_INFO);
 			if (defined('NOREDIRECTBYMAINTOLOGIN')) {
+				// When used with NOREDIRECTBYMAINTOLOGIN set, the http header must already be set when including the main.
+				// See example with selectsearchbox.php. This case is reserverd for the selectesearchbox.php so we can
+				// report a message to ask to login when search ajax component is used after a timeout.
+				//top_httphead();
 				return 'ERROR_NOT_LOGGED';
 			} else {
 				if ($_SERVER["HTTP_USER_AGENT"] == 'securitytest') {
 					http_response_code(401); // It makes easier to understand if session was broken during security tests
 				}
-				dol_loginfunction($langs, $conf, (!empty($mysoc) ? $mysoc : ''));
+				dol_loginfunction($langs, $conf, (!empty($mysoc) ? $mysoc : ''));	// This include http headers
 			}
 			exit;
 		}
@@ -1242,8 +1246,7 @@ if (!defined('NOLOGIN')) {
 		// If not active, we refuse the user
 		$langs->loadLangs(array("errors", "other"));
 		dol_syslog("Authentication KO as login is disabled", LOG_NOTICE);
-		accessforbidden($langs->trans("ErrorLoginDisabled"));
-		exit;
+		accessforbidden("ErrorLoginDisabled");
 	}
 
 	// Load permissions

+ 2 - 2
htdocs/modulebuilder/index.php

@@ -82,10 +82,10 @@ $idmodule= GETPOST('idmodule', 'alpha');
 
 // Security check
 if (!isModEnabled('modulebuilder')) {
-	accessforbidden();
+	accessforbidden('Module ModuleBuilder not enabled');
 }
 if (!$user->admin && empty($conf->global->MODULEBUILDER_FOREVERYONE)) {
-	accessforbidden($langs->trans('ModuleBuilderNotAllowed'));
+	accessforbidden('ModuleBuilderNotAllowed');
 }
 
 

+ 1 - 5
htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php

@@ -46,12 +46,8 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets
 	 */
 	public function __construct($db)
 	{
-		global $conf;
-
 		$this->db = $db;
-		if (is_array($conf->modules)) {
-			$this->enabled = in_array('mymodule', $conf->modules) ? 1 : 0;
-		}
+		$this->enabled = isModEnabled('mymodule');
 	}
 
 

+ 0 - 1
htdocs/modulebuilder/template/myobject_agenda.php

@@ -38,7 +38,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');	// Disable all Content Security Policies
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification

+ 1 - 3
htdocs/modulebuilder/template/myobject_card.php

@@ -38,7 +38,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');	// Disable all Content Security Policies
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification
@@ -248,8 +247,7 @@ llxHeader('', $title, $help_url);
 // Part to create
 if ($action == 'create') {
 	if (empty($permissiontoadd)) {
-		accessforbidden($langs->trans('NotEnoughPermissions'), 0, 1);
-		exit;
+		accessforbidden('NotEnoughPermissions', 0, 1);
 	}
 
 	print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("MyObject")), '', 'object_'.$object->picto);

+ 91 - 92
htdocs/modulebuilder/template/myobject_document.php

@@ -38,7 +38,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');				// Disable all Content Security Policies
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification
@@ -143,7 +142,13 @@ if ($enablepermissioncheck) {
 if (!isModEnabled("mymodule")) {
 	accessforbidden();
 }
-if (!$permissiontoread) accessforbidden();
+if (!$permissiontoread) {
+	accessforbidden();
+}
+if (empty($object->id)) {
+	accessforbidden();
+}
+
 
 
 /*
@@ -164,100 +169,94 @@ $help_url = '';
 //$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
 llxHeader('', $title, $help_url);
 
-if ($object->id) {
-	/*
-	 * Show tabs
-	 */
-	$head = myobjectPrepareHead($object);
-
-	print dol_get_fiche_head($head, 'document', $langs->trans("MyObject"), -1, $object->picto);
-
-
-	// Build file list
-	$filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1);
-	$totalsize = 0;
-	foreach ($filearray as $key => $file) {
-		$totalsize += $file['size'];
-	}
-
-	// Object card
-	// ------------------------------------------------------------
-	$linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
-
-	$morehtmlref = '<div class="refidno">';
-	/*
-	 // Ref customer
-	 $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
-	 $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
-	 // Thirdparty
-	 $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
-	 // Project
-	 if (!empty($conf->project->enabled))
-	 {
-	 $langs->load("projects");
-	 $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
-	 if ($permissiontoadd)
-	 {
-	 if ($action != 'classify')
-	 //$morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
-	 $morehtmlref.=' : ';
-	 if ($action == 'classify') {
-	 //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
-	 $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
-	 $morehtmlref.='<input type="hidden" name="action" value="classin">';
-	 $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
-	 $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
-	 $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
-	 $morehtmlref.='</form>';
-	 } else {
-	 $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
-	 }
-	 } else {
-	 if (!empty($object->fk_project)) {
-	 $proj = new Project($db);
-	 $proj->fetch($object->fk_project);
-	 $morehtmlref .= ': '.$proj->getNomUrl();
-	 } else {
-	 $morehtmlref .= '';
-	 }
-	 }
-	 }*/
-	$morehtmlref .= '</div>';
-
-	dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-	print '<div class="fichecenter">';
-
-	print '<div class="underbanner clearboth"></div>';
-	print '<table class="border centpercent tableforfield">';
-
-	// Number of files
-	print '<tr><td class="titlefield">'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>';
-
-	// Total size
-	print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td colspan="3">'.$totalsize.' '.$langs->trans("bytes").'</td></tr>';
-
-	print '</table>';
-
-	print '</div>';
-
-	print dol_get_fiche_end();
-
-	$modulepart = 'mymodule';
-	//$permissiontoadd = $user->rights->mymodule->myobject->write;
-	$permissiontoadd = 1;
-	//$permtoedit = $user->rights->mymodule->myobject->write;
-	$permtoedit = 1;
-	$param = '&id='.$object->id;
+// Show tabs
+$head = myobjectPrepareHead($object);
 
-	//$relativepathwithnofile='myobject/' . dol_sanitizeFileName($object->id).'/';
-	$relativepathwithnofile = 'myobject/'.dol_sanitizeFileName($object->ref).'/';
+print dol_get_fiche_head($head, 'document', $langs->trans("MyObject"), -1, $object->picto);
 
-	include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php';
-} else {
-	accessforbidden('', 0, 1);
+
+// Build file list
+$filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1);
+$totalsize = 0;
+foreach ($filearray as $key => $file) {
+	$totalsize += $file['size'];
 }
 
+// Object card
+// ------------------------------------------------------------
+$linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
+
+$morehtmlref = '<div class="refidno">';
+/*
+ // Ref customer
+ $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
+ $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
+ // Thirdparty
+ $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
+ // Project
+ if (!empty($conf->project->enabled))
+ {
+ $langs->load("projects");
+ $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
+ if ($permissiontoadd)
+ {
+ if ($action != 'classify')
+ //$morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
+ $morehtmlref.=' : ';
+ if ($action == 'classify') {
+ //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
+ $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
+ $morehtmlref.='<input type="hidden" name="action" value="classin">';
+ $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
+ $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
+ $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
+ $morehtmlref.='</form>';
+ } else {
+ $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
+ }
+ } else {
+ if (!empty($object->fk_project)) {
+ $proj = new Project($db);
+ $proj->fetch($object->fk_project);
+ $morehtmlref .= ': '.$proj->getNomUrl();
+ } else {
+ $morehtmlref .= '';
+ }
+ }
+ }*/
+$morehtmlref .= '</div>';
+
+dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
+
+print '<div class="fichecenter">';
+
+print '<div class="underbanner clearboth"></div>';
+print '<table class="border centpercent tableforfield">';
+
+// Number of files
+print '<tr><td class="titlefield">'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>';
+
+// Total size
+print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td colspan="3">'.$totalsize.' '.$langs->trans("bytes").'</td></tr>';
+
+print '</table>';
+
+print '</div>';
+
+print dol_get_fiche_end();
+
+$modulepart = 'mymodule';
+//$permissiontoadd = $user->rights->mymodule->myobject->write;
+$permissiontoadd = 1;
+//$permtoedit = $user->rights->mymodule->myobject->write;
+$permtoedit = 1;
+$param = '&id='.$object->id;
+
+//$relativepathwithnofile='myobject/' . dol_sanitizeFileName($object->id).'/';
+$relativepathwithnofile = 'myobject/'.dol_sanitizeFileName($object->ref).'/';
+
+include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php';
+
 // End of page
 llxFooter();
 $db->close();

+ 0 - 1
htdocs/modulebuilder/template/myobject_list.php

@@ -38,7 +38,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');	// Disable all Content Security Policies
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification

+ 0 - 1
htdocs/modulebuilder/template/myobject_note.php

@@ -38,7 +38,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');				// Disable all Content Security Policies
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification

+ 0 - 1
htdocs/modulebuilder/template/scripts/mymodule.php

@@ -39,7 +39,6 @@
 //if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');					// Do not check IP defined into conf $dolibarr_main_restrict_ip
 //if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');					// Force lang to a particular value
 //if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');	// Force authentication handler
-//if (! defined("NOREDIRECTBYMAINTOLOGIN"))  define('NOREDIRECTBYMAINTOLOGIN', 1);		// The main.inc.php does not make a redirect if not logged, instead show simple error message
 //if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');		// Force use of CSRF protection with tokens even for GET
 //if (! defined('NOBROWSERNOTIF'))     		 define('NOBROWSERNOTIF', '1');				// Disable browser notification
 if (!defined('NOSESSION')) define('NOSESSION', '1');	// On CLI mode, no need to use web sessions

+ 7 - 4
htdocs/mrp/mo_card.php

@@ -16,11 +16,12 @@
  */
 
 /**
- *   	\file       mo_card.php
- *		\ingroup    mrp
- *		\brief      Page to create/edit/view mo
+ *    \file       htdocs/mrp/mo_card.php
+ *    \ingroup    mrp
+ *    \brief      Page to create/edit/view MO Manufacturing Order
  */
 
+
 // Load Dolibarr environment
 require '../main.inc.php';
 
@@ -35,7 +36,8 @@ require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php';
 
 
 // Load translation files required by the page
-$langs->loadLangs(array("mrp", "other"));
+$langs->loadLangs(array('mrp', 'other'));
+
 
 // Get parameters
 $id = GETPOST('id', 'int');
@@ -97,6 +99,7 @@ if (GETPOST('fk_bom', 'int') > 0) {
 $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
 $result = restrictedArea($user, 'mrp', $object->id, 'mrp_mo', '', 'fk_soc', 'rowid', $isdraft);
 
+// Permissions
 $permissionnote = $user->rights->mrp->write; // Used by the include of actions_setnotes.inc.php
 $permissiondellink = $user->rights->mrp->write; // Used by the include of actions_dellink.inc.php
 $permissiontoadd = $user->rights->mrp->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php

+ 9 - 6
htdocs/multicurrency/multicurrency_rate.php

@@ -27,9 +27,9 @@
  */
 
 /**
- *  \file       htdocs/multicurrency/multicurrency_rate.php
- *  \ingroup    multicurrency
- *  \brief      Page to list multicurrency rate
+ *    \file       htdocs/multicurrency/multicurrency_rate.php
+ *    \ingroup    multicurrency
+ *    \brief      Page to list multicurrency rate
  */
 
 // Load Dolibarr environment
@@ -37,9 +37,11 @@ require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/multicurrency.lib.php';
 
+
 // Load translation files required by the page
 $langs->loadLangs(array('multicurrency'));
 
+// Get Parameters
 $action				= GETPOST('action', 'alpha');
 $massaction			= GETPOST('massaction', 'alpha');
 $show_files			= GETPOST('show_files', 'int');
@@ -70,12 +72,13 @@ if (!$sortfield) $sortfield = "cr.date_sync";
 if (!$sortorder) $sortorder = "DESC";
 
 
-// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array of hooks
+// Initialize technical objects
 $object = new CurrencyRate($db);
-
-$extrafields = new ExtraFields($db);
 $form = new Form($db);
+$extrafields = new ExtraFields($db);
+
 
+// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array of hooks
 $hookmanager->initHooks(array('EditorRatelist', 'globallist'));
 
 if (empty($action)) {

+ 6 - 5
htdocs/opensurvey/card.php

@@ -18,16 +18,16 @@
  */
 
 /**
- *	\file       htdocs/opensurvey/card.php
- *	\ingroup    opensurvey
- *	\brief      Page to edit survey
+ *    \file       htdocs/opensurvey/card.php
+ *    \ingroup    opensurvey
+ *    \brief      Page to edit survey
  */
 
 // Load Dolibarr environment
 require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
 require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
 require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
 require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
 require_once DOL_DOCUMENT_ROOT."/opensurvey/lib/opensurvey.lib.php";
 
@@ -37,7 +37,7 @@ if (empty($user->rights->opensurvey->read)) {
 	accessforbidden();
 }
 
-// Initialisation des variables
+// Initialize Variables
 $action = GETPOST('action', 'aZ09');
 $cancel = GETPOST('cancel', 'alpha');
 
@@ -47,6 +47,7 @@ if (GETPOST('id')) {
 	$numsondage = (string) GETPOST('id', 'alpha');
 }
 
+// Initialize objects
 $object = new Opensurveysondage($db);
 
 $result = $object->fetch(0, $numsondage);

+ 7 - 5
htdocs/opensurvey/exportcsv.php

@@ -1,6 +1,6 @@
 <?php
-/* Copyright (C) 2013      Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2014 Marcos García				<marcosgdf@gmail.com>
+/* Copyright (C) 2013      Laurent Destailleur        <eldy@users.sourceforge.net>
+ * Copyright (C) 2014      Marcos García              <marcosgdf@gmail.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
@@ -17,9 +17,9 @@
  */
 
 /**
- *	\file       htdocs/opensurvey/exportcsv.php
- *	\ingroup    opensurvey
- *	\brief      Page to list surveys
+ *    \file       htdocs/opensurvey/exportcsv.php
+ *    \ingroup    opensurvey
+ *    \brief      Page to list surveys
  */
 
 
@@ -29,12 +29,14 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
 require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
 require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
 
+
 $action = GETPOST('action', 'aZ09');
 $numsondage = '';
 if (GETPOST('id')) {
 	$numsondage = GETPOST("id", 'alpha');
 }
 
+// Initialize Objects
 $object = new Opensurveysondage($db);
 $result = $object->fetch(0, $numsondage);
 if ($result <= 0) {

+ 10 - 9
htdocs/product/card.php

@@ -44,19 +44,19 @@
 
 // Load Dolibarr environment
 require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php';
-require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
-require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php';
+require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
 
-if (isModEnabled("propal")) {
+if (isModEnabled('propal')) {
 	require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
 }
 if (isModEnabled('facture')) {
@@ -91,7 +91,7 @@ $mesg = ''; $error = 0; $errors = array();
 $refalreadyexists = 0;
 
 // Get parameters
-$id = GETPOST('id', 'int');
+$id  = GETPOST('id', 'int');
 $ref = (GETPOSTISSET('ref') ? GETPOST('ref', 'alpha') : null);
 $type = (GETPOSTISSET('type') ? GETPOST('type', 'int') : Product::TYPE_PRODUCT);
 $action = (GETPOST('action', 'alpha') ? GETPOST('action', 'alpha') : 'view');
@@ -184,7 +184,8 @@ if ($object->id > 0) {
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
 $hookmanager->initHooks(array('productcard', 'globalcard'));
 
-$usercanread = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->lire) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->lire));
+// Permissions
+$usercanread   = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->lire) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->lire));
 $usercancreate = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->creer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->creer));
 $usercandelete = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->supprimer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->supprimer));
 

+ 17 - 1
htdocs/projet/class/projectstats.class.php

@@ -32,6 +32,11 @@ class ProjectStats extends Stats
 	public $status;
 	public $opp_status;
 
+	//SQL stat
+	public $field;
+	public $from;
+	public $where;
+
 
 	/**
 	 * Constructor
@@ -46,6 +51,18 @@ class ProjectStats extends Stats
 
 		require_once 'project.class.php';
 		$this->project = new Project($this->db);
+
+		$this->from = MAIN_DB_PREFIX.$this->project->table_element;
+		$this->field = 'opp_amount';
+		$this->where = " entity = ".$conf->entity;
+		if ($this->socid > 0) {
+			$this->where .= " AND fk_soc = ".((int) $this->socid);
+		}
+		if (is_array($this->userid) && count($this->userid) > 0) {
+			$this->where .= ' AND fk_user IN ('.$this->db->sanitize(join(',', $this->userid)).')';
+		} elseif ($this->userid > 0) {
+			$this->where .= " AND fk_user = ".((int) $this->userid);
+		}
 	}
 
 
@@ -538,7 +555,6 @@ class ProjectStats extends Stats
 	{
 		$sql = "SELECT date_format(datef,'%m') as dm, AVG(f.".$this->field.")";
 		$sql .= " FROM ".$this->from;
-		$sql .= $this->join;
 		$sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
 		$sql .= " AND ".$this->where;
 		$sql .= " GROUP BY dm";

+ 1 - 1
htdocs/public/agenda/agendaexport.php

@@ -85,7 +85,7 @@ require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
 
 // Security check
 if (empty($conf->agenda->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Agenda not enabled');
 }
 
 // Not older than

+ 1 - 1
htdocs/public/cron/cron_run_jobs_by_url.php

@@ -75,7 +75,7 @@ $langs->loadLangs(array("admin", "cron", "dict"));
 
 // Security check
 if (empty($conf->cron->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Cron not enabled');
 }
 
 

+ 1 - 1
htdocs/public/demo/index.php

@@ -52,7 +52,7 @@ $conf->dol_use_jmobile = GETPOST('dol_use_jmobile', 'int');
 // Security check
 global $dolibarr_main_demo;
 if (empty($dolibarr_main_demo)) {
-	accessforbidden('Parameter dolibarr_main_demo must be defined in conf file with value "default login,default pass" to enable the demo entry page', 0, 0, 1);
+	httponly_accessforbidden('Parameter dolibarr_main_demo must be defined in conf file with value "default login,default pass" to enable the demo entry page');
 }
 
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context

+ 1 - 1
htdocs/public/donations/donateurs_code.php

@@ -61,7 +61,7 @@ require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
 
 // Security check
 if (empty($conf->don->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Donation not enabled');
 }
 
 

+ 1 - 1
htdocs/public/eventorganization/attendee_new.php

@@ -139,7 +139,7 @@ $user->loadDefaultValues();
 
 // Security check
 if (empty($conf->eventorganization->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Event organization not enabled');
 }
 
 

+ 1 - 1
htdocs/public/eventorganization/subscriptionok.php

@@ -78,7 +78,7 @@ if ($securekeyreceived != $securekeytocompare) {
 
 // Security check
 if (empty($conf->eventorganization->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Event organization not enabled');
 }
 
 

+ 2 - 3
htdocs/public/members/new.php

@@ -86,12 +86,11 @@ $langs->loadLangs(array("main", "members", "companies", "install", "other"));
 
 // Security check
 if (empty($conf->adherent->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Membership not enabled');
 }
 
 if (empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
-	print $langs->trans("Auto subscription form for public visitors has not been enabled");
-	exit;
+	httponly_accessforbidden("Auto subscription form for public visitors has not been enabled");
 }
 
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context

+ 1 - 1
htdocs/public/members/public_card.php

@@ -54,7 +54,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 
 // Security check
 if (empty($conf->adherent->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Memebership no enabled');
 }
 
 

+ 1 - 1
htdocs/public/members/public_list.php

@@ -50,7 +50,7 @@ require '../../main.inc.php';
 
 // Security check
 if (empty($conf->adherent->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Membership not enabled');
 }
 
 

+ 15 - 19
htdocs/public/onlinesign/newonlinesign.php

@@ -82,13 +82,6 @@ $ref = $REF = GETPOST("ref", 'alpha');
 if (empty($source)) {
 	$source = 'proposal';
 }
-
-if (!$action) {
-	if ($source && !$ref) {
-		print $langs->trans('ErrorBadParameters')." - ref missing";
-		exit;
-	}
-}
 if (!empty($refusepropal)) {
 	$action = "refusepropal";
 }
@@ -124,15 +117,12 @@ $urlko = preg_replace('/&$/', '', $urlko); // Remove last &
 $creditor = $mysoc->name;
 
 $type = $source;
-if ($source == 'proposal') {
-	require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
-	$object = new Propal($db);
-	$result= $object->fetch(0, $ref, '', $entity);
-} else {
-	accessforbidden('Bad value for source');
-	exit;
-}
 
+if (!$action) {
+	if ($source && !$ref) {
+		httponly_accessforbidden($langs->trans('ErrorBadParameters')." - ref missing", 400, 1);
+	}
+}
 
 // Check securitykey
 $securekeyseed = '';
@@ -140,10 +130,16 @@ if ($source == 'proposal') {
 	$securekeyseed = getDolGlobalString('PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN');
 }
 
-if (!dol_verifyHash($securekeyseed.$type.$ref.(!isModEnabled('multicompany') ? '' : $entity), $SECUREKEY, '0')) {
-	http_response_code(403);
-	print 'Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref);
-	exit(-1);
+if (!dol_verifyHash($securekeyseed.$type.$ref.(isModEnabled('multicompany') ? $entity : ''), $SECUREKEY, '0')) {
+	httponly_accessforbidden('Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref), 403, 1);
+}
+
+if ($source == 'proposal') {
+	require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
+	$object = new Propal($db);
+	$result= $object->fetch(0, $ref, '', $entity);
+} else {
+	httponly_accessforbidden($langs->trans('ErrorBadParameters')." - Bad value for source", 400, 1);
 }
 
 

+ 5 - 5
htdocs/public/opensurvey/studs.php

@@ -60,7 +60,7 @@ $canbemodified = ((empty($object->date_fin) || $object->date_fin > dol_now()) &&
 
 // Security check
 if (empty($conf->opensurvey->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Survey not enabled');
 }
 
 
@@ -75,7 +75,7 @@ $listofvoters = explode(',', $_SESSION["savevoter"]);
 // Add comment
 if (GETPOST('ajoutcomment', 'alpha')) {
 	if (!$canbemodified) {
-		accessforbidden('', 0, 0, 1);
+		httponly_accessforbidden('ErrorForbidden');
 	}
 
 	$error = 0;
@@ -109,7 +109,7 @@ if (GETPOST('ajoutcomment', 'alpha')) {
 // Add vote
 if (GETPOST("boutonp") || GETPOST("boutonp.x") || GETPOST("boutonp_x")) {		// boutonp for chrome, boutonp_x for firefox
 	if (!$canbemodified) {
-		accessforbidden('', 0, 0, 1);
+		httponly_accessforbidden('ErrorForbidden');
 	}
 
 	//Si le nom est bien entré
@@ -215,7 +215,7 @@ if ($testmodifier) {
 	}
 
 	if (!$canbemodified) {
-		accessforbidden('', 0, 0, 1);
+		httponly_accessforbidden('ErrorForbidden');
 	}
 
 	$idtomodify = GETPOST("idtomodify".$modifier);
@@ -233,7 +233,7 @@ if ($testmodifier) {
 $idcomment = GETPOST('deletecomment', 'int');
 if ($idcomment) {
 	if (!$canbemodified) {
-		accessforbidden('', 0, 0, 1);
+		httponly_accessforbidden('ErrorForbidden');
 	}
 
 	$resql = $object->deleteComment($idcomment);

+ 2 - 3
htdocs/public/partnership/new.php

@@ -72,12 +72,11 @@ $langs->loadLangs(array("main", "members", "partnership", "companies", "install"
 
 // Security check
 if (empty($conf->partnership->enabled)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('Module Partnership not enabled');
 }
 
 if (empty($conf->global->PARTNERSHIP_ENABLE_PUBLIC)) {
-	print $langs->trans("Auto subscription form for public visitors has not been enabled");
-	exit;
+	httponly_accessforbidden("Auto subscription form for public visitors has not been enabled");
 }
 
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context

+ 1 - 1
htdocs/public/payment/paymentko.php

@@ -109,7 +109,7 @@ if (!empty($conf->stripe->enabled)) {
 
 // Security check
 if (empty($validpaymentmethod)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('No valid payment mode');
 }
 
 

+ 1 - 1
htdocs/public/payment/paymentok.php

@@ -139,7 +139,7 @@ if (!empty($conf->stripe->enabled)) {
 
 // Security check
 if (empty($validpaymentmethod)) {
-	accessforbidden('', 0, 0, 1);
+	httponly_accessforbidden('No valid payment mode');
 }
 
 

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff