浏览代码

Merge + Clean duplicate trigger code. We must use the context.

Laurent Destailleur 2 年之前
父节点
当前提交
54d1250887
共有 34 个文件被更改,包括 262 次插入204 次删除
  1. 4 0
      htdocs/admin/agenda.php
  2. 4 2
      htdocs/admin/notification.php
  3. 10 0
      htdocs/admin/pdf.php
  4. 2 2
      htdocs/admin/system/security.php
  5. 6 1
      htdocs/core/ajax/fileupload.php
  6. 16 11
      htdocs/core/ajax/onlineSign.php
  7. 36 2
      htdocs/core/class/fileupload.class.php
  8. 1 1
      htdocs/core/class/html.formcompany.class.php
  9. 4 4
      htdocs/core/class/html.formticket.class.php
  10. 34 19
      htdocs/core/class/notify.class.php
  11. 15 15
      htdocs/core/modules/modPartnership.class.php
  12. 4 1
      htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php
  13. 3 1
      htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
  14. 4 3
      htdocs/core/triggers/interface_50_modNotification_Notification.class.php
  15. 4 4
      htdocs/core/website.inc.php
  16. 1 1
      htdocs/includes/tcpdi/tcpdi.php
  17. 9 2
      htdocs/install/mysql/data/llx_c_action_trigger.sql
  18. 1 2
      htdocs/install/mysql/migration/16.0.0-17.0.0.sql
  19. 6 0
      htdocs/install/mysql/migration/17.0.0-18.0.0.sql
  20. 1 0
      htdocs/install/mysql/tables/llx_c_action_trigger.sql
  21. 3 0
      htdocs/install/mysql/tables/llx_notify_def.sql
  22. 0 2
      htdocs/langs/en_US/other.lang
  23. 1 0
      htdocs/langs/en_US/partnership.lang
  24. 4 4
      htdocs/main.inc.php
  25. 1 1
      htdocs/modulebuilder/template/myobject_card.php
  26. 0 74
      htdocs/partnership/admin/about.php
  27. 3 0
      htdocs/partnership/class/partnership.class.php
  28. 53 47
      htdocs/partnership/partnership_card.php
  29. 3 4
      htdocs/public/onlinesign/newonlinesign.php
  30. 19 0
      htdocs/public/partnership/new.php
  31. 3 0
      htdocs/ticket/agenda.php
  32. 1 1
      htdocs/ticket/contact.php
  33. 3 0
      htdocs/ticket/document.php
  34. 3 0
      htdocs/ticket/messaging.php

+ 4 - 0
htdocs/admin/agenda.php

@@ -194,6 +194,10 @@ if (!empty($triggers)) {
 			if ($trigger['code'] == 'FICHINTER_CLASSIFY_UNBILLED' && empty($conf->global->FICHINTER_CLASSIFY_BILLED)) {
 			if ($trigger['code'] == 'FICHINTER_CLASSIFY_UNBILLED' && empty($conf->global->FICHINTER_CLASSIFY_BILLED)) {
 				continue;
 				continue;
 			}
 			}
+			if ($trigger['code'] == 'ACTION_CREATE') {
+				// This is the trigger to add an event, enabling it will create infinite loop
+				continue;
+			}
 
 
 			if ($search_event === '' || preg_match('/'.preg_quote($search_event, '/').'/i', $trigger['code'])) {
 			if ($search_event === '' || preg_match('/'.preg_quote($search_event, '/').'/i', $trigger['code'])) {
 				print '<!-- '.$trigger['position'].' -->';
 				print '<!-- '.$trigger['position'].' -->';

+ 4 - 2
htdocs/admin/notification.php

@@ -265,7 +265,7 @@ print load_fiche_titre($title, '', 'email');
 // Load array of available notifications
 // Load array of available notifications
 $notificationtrigger = new InterfaceNotification($db);
 $notificationtrigger = new InterfaceNotification($db);
 $listofnotifiedevents = $notificationtrigger->getListOfManagedEvents();
 $listofnotifiedevents = $notificationtrigger->getListOfManagedEvents();
-
+var_dump($listofnotifiedevents);
 // Editing global variables not related to a specific theme
 // Editing global variables not related to a specific theme
 $constantes = array();
 $constantes = array();
 foreach ($listofnotifiedevents as $notifiedevent) {
 foreach ($listofnotifiedevents as $notifiedevent) {
@@ -427,11 +427,13 @@ foreach ($listofnotifiedevents as $notifiedevent) {
 	} elseif ($notifiedevent['elementtype'] == 'expensereport' || $notifiedevent['elementtype'] == 'expense_report') {
 	} elseif ($notifiedevent['elementtype'] == 'expensereport' || $notifiedevent['elementtype'] == 'expense_report') {
 		$elementPicto = 'expensereport';
 		$elementPicto = 'expensereport';
 		$elementLabel = $langs->trans('ExpenseReport');
 		$elementLabel = $langs->trans('ExpenseReport');
+	} elseif ($notifiedevent['elementtype'] == 'agenda') {
+		$elementPicto = 'action';
 	}
 	}
 
 
 	$labelfortrigger = 'AmountHT';
 	$labelfortrigger = 'AmountHT';
 	$codehasnotrigger = 0;
 	$codehasnotrigger = 0;
-	if (preg_match('/^HOLIDAY/', $notifiedevent['code'])) {
+	if (preg_match('/^(ACTION|HOLIDAY)/', $notifiedevent['code'])) {
 		$codehasnotrigger++;
 		$codehasnotrigger++;
 	}
 	}
 
 

+ 10 - 0
htdocs/admin/pdf.php

@@ -271,9 +271,19 @@ print '<input type="hidden" name="action" value="update">';
 clearstatcache();
 clearstatcache();
 
 
 
 
+if (getDolGlobalString('PDF_SECURITY_ENCRYPTION')) {
+	print '<div class="warning">';
+	print 'The not supported and hidden option PDF_SECURITY_ENCRYPTION has been enabled. This means a lof of feature related to PDF will be broken, like mass PDF generation or online signature of PDF.'."\n";
+	print 'You should disable this option.';
+	print '</div>';
+}
+
+
+
 // Misc options
 // Misc options
 print load_fiche_titre($langs->trans("DictionaryPaperFormat"), '', '');
 print load_fiche_titre($langs->trans("DictionaryPaperFormat"), '', '');
 
 
+
 print '<div class="div-table-responsive-no-min">';
 print '<div class="div-table-responsive-no-min">';
 print '<table summary="more" class="noborder centpercent">';
 print '<table summary="more" class="noborder centpercent">';
 print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("Parameters").'</td><td width="200px">'.$langs->trans("Value").'</td></tr>';
 print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("Parameters").'</td><td width="200px">'.$langs->trans("Value").'</td></tr>';

+ 2 - 2
htdocs/admin/system/security.php

@@ -580,11 +580,11 @@ print '<br>';
 print '<strong>MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED</strong> = '.getDolGlobalString('MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED', '<span class="opacitymedium">'.$langs->trans("Undefined").' &nbsp; ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)</span>')."<br>";
 print '<strong>MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED</strong> = '.getDolGlobalString('MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED', '<span class="opacitymedium">'.$langs->trans("Undefined").' &nbsp; ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)</span>')."<br>";
 print '<br>';
 print '<br>';
 
 
-$examplecsprule = "frame-ancestors 'self'; img-src * data:; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com;";
+$examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
 print '<strong>MAIN_SECURITY_FORCECSPRO</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCECSP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
 print '<strong>MAIN_SECURITY_FORCECSPRO</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCECSP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
 print '<br>';
 print '<br>';
 
 
-$examplecsprule = "frame-ancestors 'self'; img-src * data:; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com;";
+$examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
 print '<strong>MAIN_SECURITY_FORCECSP</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCERP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
 print '<strong>MAIN_SECURITY_FORCECSP</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCERP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
 print '<br>';
 print '<br>';
 
 

+ 6 - 1
htdocs/core/ajax/fileupload.php

@@ -45,9 +45,14 @@ error_reporting(E_ALL | E_STRICT);
 $fk_element = GETPOST('fk_element', 'int');
 $fk_element = GETPOST('fk_element', 'int');
 $element = GETPOST('element', 'alpha');
 $element = GETPOST('element', 'alpha');
 
 
-
 $upload_handler = new FileUpload(null, $fk_element, $element);
 $upload_handler = new FileUpload(null, $fk_element, $element);
 
 
+// Feature not enabled. Warning feature not used and not secured so disabled.
+if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+	return;
+}
+
+
 /*
 /*
  * View
  * View
  */
  */

+ 16 - 11
htdocs/core/ajax/onlineSign.php

@@ -91,7 +91,8 @@ if (empty($SECUREKEY) || !dol_verifyHash($securekeyseed.$type.$ref.(!isModEnable
 top_httphead();
 top_httphead();
 
 
 if ($action == "importSignature") {
 if ($action == "importSignature") {
-	if (!empty($signature) && $signature[0] == "image/png;base64") {
+	$issignatureok = (!empty($signature) && $signature[0] == "image/png;base64");
+	if ($issignatureok) {
 		$signature = $signature[1];
 		$signature = $signature[1];
 		$data = base64_decode($signature);
 		$data = base64_decode($signature);
 
 
@@ -148,7 +149,6 @@ if ($action == "importSignature") {
 							$pdf->SetCompression(false);
 							$pdf->SetCompression(false);
 						}
 						}
 
 
-
 						//$pdf->Open();
 						//$pdf->Open();
 						$pagecount = $pdf->setSourceFile($sourcefile);		// original PDF
 						$pagecount = $pdf->setSourceFile($sourcefile);		// original PDF
 
 
@@ -160,7 +160,7 @@ if ($action == "importSignature") {
 								$pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
 								$pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
 								$pdf->useTemplate($tppl);
 								$pdf->useTemplate($tppl);
 							} catch (Exception $e) {
 							} catch (Exception $e) {
-								dol_syslog("Error when manipulating some PDF by onlineSign: ".$e->getMessage(), LOG_ERR);
+								dol_syslog("Error when manipulating the PDF ".$sourcefile." by onlineSign: ".$e->getMessage(), LOG_ERR);
 								$response = $e->getMessage();
 								$response = $e->getMessage();
 								$error++;
 								$error++;
 							}
 							}
@@ -218,9 +218,6 @@ if ($action == "importSignature") {
 				}
 				}
 
 
 				if (!$error) {
 				if (!$error) {
-					$db->commit();
-					$response = "success";
-					setEventMessages("PropalSigned", null, 'warnings');
 					if (method_exists($object, 'call_trigger')) {
 					if (method_exists($object, 'call_trigger')) {
 						//customer is not a user !?! so could we use same user as validation ?
 						//customer is not a user !?! so could we use same user as validation ?
 						$user = new User($db);
 						$user = new User($db);
@@ -229,17 +226,25 @@ if ($action == "importSignature") {
 						$result = $object->call_trigger('PROPAL_CLOSE_SIGNED', $user);
 						$result = $object->call_trigger('PROPAL_CLOSE_SIGNED', $user);
 						if ($result < 0) {
 						if ($result < 0) {
 							$error++;
 							$error++;
+							$response = "error in trigger ".$object->error;
+						} else {
+							$response = "success";
 						}
 						}
-						$result = $object->call_trigger('PROPAL_CLOSE_SIGNED_WEB', $user);
-						if ($result < 0) {
-							$error++;
-						}
+					} else {
+						$response = "success";
 					}
 					}
 				} else {
 				} else {
-					$db->rollback();
 					$error++;
 					$error++;
 					$response = "error sql";
 					$response = "error sql";
 				}
 				}
+
+				if (!$error) {
+					$db->commit();
+					$response = "success";
+					setEventMessages("PropalSigned", null, 'warnings');
+				} else {
+					$db->rollback();
+				}
 			}
 			}
 		} elseif ($mode == 'contract') {
 		} elseif ($mode == 'contract') {
 			require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
 			require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';

+ 36 - 2
htdocs/core/class/fileupload.class.php

@@ -46,6 +46,12 @@ class FileUpload
 		global $db, $conf;
 		global $db, $conf;
 		global $object;
 		global $object;
 		global $hookmanager;
 		global $hookmanager;
+
+		// Feature not enabled. Warning feature not used and not secured so disabled.
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		$hookmanager->initHooks(array('fileupload'));
 		$hookmanager->initHooks(array('fileupload'));
 
 
 		$this->fk_element = $fk_element;
 		$this->fk_element = $fk_element;
@@ -238,6 +244,10 @@ class FileUpload
 	 */
 	 */
 	protected function getFileObject($file_name)
 	protected function getFileObject($file_name)
 	{
 	{
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		$file_path = $this->options['upload_dir'].$file_name;
 		$file_path = $this->options['upload_dir'].$file_name;
 		if (is_file($file_path) && $file_name[0] !== '.') {
 		if (is_file($file_path) && $file_name[0] !== '.') {
 			$file = new stdClass();
 			$file = new stdClass();
@@ -278,6 +288,10 @@ class FileUpload
 	{
 	{
 		global $maxwidthmini, $maxheightmini;
 		global $maxwidthmini, $maxheightmini;
 
 
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		$file_path = $this->options['upload_dir'].$file_name;
 		$file_path = $this->options['upload_dir'].$file_name;
 		$new_file_path = $options['upload_dir'].$file_name;
 		$new_file_path = $options['upload_dir'].$file_name;
 
 
@@ -309,6 +323,10 @@ class FileUpload
 	 */
 	 */
 	protected function validate($uploaded_file, $file, $error, $index)
 	protected function validate($uploaded_file, $file, $error, $index)
 	{
 	{
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		if ($error) {
 		if ($error) {
 			$file->error = $error;
 			$file->error = $error;
 			return false;
 			return false;
@@ -399,8 +417,8 @@ class FileUpload
 		// Also remove control characters and spaces (\x00..\x20) around the filename:
 		// Also remove control characters and spaces (\x00..\x20) around the filename:
 		$file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
 		$file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
 		// Add missing file extension for known image types:
 		// Add missing file extension for known image types:
-		if (strpos($file_name, '.') === false &&
-				preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
+		$matches = array();
+		if (strpos($file_name, '.') === false && preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
 			$file_name .= '.'.$matches[1];
 			$file_name .= '.'.$matches[1];
 		}
 		}
 		if ($this->options['discard_aborted_uploads']) {
 		if ($this->options['discard_aborted_uploads']) {
@@ -424,6 +442,10 @@ class FileUpload
 	 */
 	 */
 	protected function handleFileUpload($uploaded_file, $name, $size, $type, $error, $index)
 	protected function handleFileUpload($uploaded_file, $name, $size, $type, $error, $index)
 	{
 	{
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		$file = new stdClass();
 		$file = new stdClass();
 		$file->name = $this->trimFileName($name, $type, $index);
 		$file->name = $this->trimFileName($name, $type, $index);
 		$file->mime = dol_mimetype($file->name, '', 2);
 		$file->mime = dol_mimetype($file->name, '', 2);
@@ -470,6 +492,10 @@ class FileUpload
 	 */
 	 */
 	public function get()
 	public function get()
 	{
 	{
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		$file_name = isset($_REQUEST['file']) ?
 		$file_name = isset($_REQUEST['file']) ?
 		basename(stripslashes($_REQUEST['file'])) : null;
 		basename(stripslashes($_REQUEST['file'])) : null;
 		if ($file_name) {
 		if ($file_name) {
@@ -488,6 +514,10 @@ class FileUpload
 	 */
 	 */
 	public function post()
 	public function post()
 	{
 	{
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
 		if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
 			return $this->delete();
 			return $this->delete();
 		}
 		}
@@ -543,6 +573,10 @@ class FileUpload
 	 */
 	 */
 	public function delete()
 	public function delete()
 	{
 	{
+		if (!getDolGlobalInt('MAIN_USE_JQUERY_FILEUPLOAD')) {
+			return;
+		}
+
 		$file_name = isset($_REQUEST['file']) ?
 		$file_name = isset($_REQUEST['file']) ?
 		basename(stripslashes($_REQUEST['file'])) : null;
 		basename(stripslashes($_REQUEST['file'])) : null;
 		$file_path = $this->options['upload_dir'].$file_name;
 		$file_path = $this->options['upload_dir'].$file_name;

+ 1 - 1
htdocs/core/class/html.formcompany.class.php

@@ -908,7 +908,7 @@ class FormCompany extends Form
 	 *  @param  string  $morecss        More css
 	 *  @param  string  $morecss        More css
 	 *  @return	string					HTML string with prof id
 	 *  @return	string					HTML string with prof id
 	 */
 	 */
-	public function get_input_id_prof($idprof, $htmlname, $preselected, $country_code, $morecss = 'maxwidth100onsmartphone quatrevingtpercent')
+	public function get_input_id_prof($idprof, $htmlname, $preselected, $country_code, $morecss = 'maxwidth200')
 	{
 	{
 		// phpcs:enable
 		// phpcs:enable
 		global $conf, $langs, $hookmanager;
 		global $conf, $langs, $hookmanager;

+ 4 - 4
htdocs/core/class/html.formticket.class.php

@@ -1431,7 +1431,7 @@ class FormTicket
 			$res = $ticketstat->fetch('', '', $this->track_id);
 			$res = $ticketstat->fetch('', '', $this->track_id);
 
 
 			print '<tr><td></td><td>';
 			print '<tr><td></td><td>';
-			$checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : ($conf->global->TICKETS_MESSAGE_FORCE_MAIL?'checked':''));
+			$checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : (getDolGlobalInt('TICKETS_MESSAGE_FORCE_MAIL')?'checked':''));
 			print '<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.'/> ';
 			print '<input type="checkbox" name="send_email" value="1" id="send_msg_email" '.$checkbox_selected.'/> ';
 			print '<label for="send_msg_email">'.$langs->trans('SendMessageByEmail').'</label>';
 			print '<label for="send_msg_email">'.$langs->trans('SendMessageByEmail').'</label>';
 			$texttooltip = $langs->trans("TicketMessageSendEmailHelp", '{s1}');
 			$texttooltip = $langs->trans("TicketMessageSendEmailHelp", '{s1}');
@@ -1463,7 +1463,7 @@ class FormTicket
 
 
 			// Subject
 			// Subject
 			print '<tr class="email_line"><td>'.$langs->trans('Subject').'</td>';
 			print '<tr class="email_line"><td>'.$langs->trans('Subject').'</td>';
-			print '<td><input type="text" class="text minwidth500" name="subject" value="['.$conf->global->MAIN_INFO_SOCIETE_NOM.' - '.$langs->trans("Ticket").' '.$ticketstat->ref.'] '.$langs->trans('TicketNewMessage').'" />';
+			print '<td><input type="text" class="text minwidth500" name="subject" value="['.getDolGlobalString('MAIN_INFO_SOCIETE_NOM').' - '.$langs->trans("Ticket").' '.$ticketstat->ref.'] '.$langs->trans('TicketNewMessage').'" />';
 			print '</td></tr>';
 			print '</td></tr>';
 
 
 			// Recipients / adressed-to
 			// Recipients / adressed-to
@@ -1497,8 +1497,8 @@ class FormTicket
 					}
 					}
 				}
 				}
 
 
-				if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) {
-					$sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' <small class="opacitymedium">(generic email)</small>';
+				if (getDolGlobalInt('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS')) {
+					$sendto[] = getDolGlobalString('TICKET_NOTIFICATION_EMAIL_TO').' <small class="opacitymedium">(generic email)</small>';
 				}
 				}
 
 
 				// Print recipient list
 				// Print recipient list

+ 34 - 19
htdocs/core/class/notify.class.php

@@ -71,9 +71,7 @@ class Notify
 		'ORDER_VALIDATE',
 		'ORDER_VALIDATE',
 		'PROPAL_VALIDATE',
 		'PROPAL_VALIDATE',
 		'PROPAL_CLOSE_SIGNED',
 		'PROPAL_CLOSE_SIGNED',
-		'PROPAL_CLOSE_SIGNED_WEB',
 		'PROPAL_CLOSE_REFUSED',
 		'PROPAL_CLOSE_REFUSED',
-		'PROPAL_CLOSE_REFUSED_WEB',
 		'FICHINTER_VALIDATE',
 		'FICHINTER_VALIDATE',
 		'FICHINTER_ADD_CONTACT',
 		'FICHINTER_ADD_CONTACT',
 		'ORDER_SUPPLIER_VALIDATE',
 		'ORDER_SUPPLIER_VALIDATE',
@@ -359,6 +357,7 @@ class Notify
 		global $dolibarr_main_url_root;
 		global $dolibarr_main_url_root;
 		global $action;
 		global $action;
 
 
+		// Complete the array Notify::$arrayofnotifsupported
 		if (!is_object($hookmanager)) {
 		if (!is_object($hookmanager)) {
 			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
 			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
 			$hookmanager = new HookManager($this->db);
 			$hookmanager = new HookManager($this->db);
@@ -373,13 +372,14 @@ class Notify
 			}
 			}
 		}
 		}
 
 
+		// If the trigger code is not managed by the Notification module
 		if (!in_array($notifcode, Notify::$arrayofnotifsupported)) {
 		if (!in_array($notifcode, Notify::$arrayofnotifsupported)) {
 			return 0;
 			return 0;
 		}
 		}
 
 
 		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 
 
-		dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id);
+		dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object id=".$object->id);
 
 
 		$langs->load("other");
 		$langs->load("other");
 
 
@@ -407,7 +407,7 @@ class Notify
 		// Check notification per third party
 		// Check notification per third party
 		if (!empty($object->socid) && $object->socid > 0) {
 		if (!empty($object->socid) && $object->socid > 0) {
 			$sql .= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
 			$sql .= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
-			$sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
+			$sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.threshold, n.context, n.type";
 			$sql .= " FROM ".$this->db->prefix()."socpeople as c,";
 			$sql .= " FROM ".$this->db->prefix()."socpeople as c,";
 			$sql .= " ".$this->db->prefix()."c_action_trigger as a,";
 			$sql .= " ".$this->db->prefix()."c_action_trigger as a,";
 			$sql .= " ".$this->db->prefix()."notify_def as n,";
 			$sql .= " ".$this->db->prefix()."notify_def as n,";
@@ -427,7 +427,7 @@ class Notify
 
 
 		// Check notification per user
 		// Check notification per user
 		$sql .= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
 		$sql .= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
-		$sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
+		$sql .= " a.rowid as adid, a.label, a.code, n.rowid, n.threshold, n.context, n.type";
 		$sql .= " FROM ".$this->db->prefix()."user as c,";
 		$sql .= " FROM ".$this->db->prefix()."user as c,";
 		$sql .= " ".$this->db->prefix()."c_action_trigger as a,";
 		$sql .= " ".$this->db->prefix()."c_action_trigger as a,";
 		$sql .= " ".$this->db->prefix()."notify_def as n";
 		$sql .= " ".$this->db->prefix()."notify_def as n";
@@ -439,6 +439,11 @@ class Notify
 			$sql .= " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
 			$sql .= " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
 		}
 		}
 
 
+		// Check notification fixed
+		// TODO Move part found after, into a sql here
+
+
+		// Loop on all notifications enabled
 		$result = $this->db->query($sql);
 		$result = $this->db->query($sql);
 		if ($result) {
 		if ($result) {
 			$num = $this->db->num_rows($result);
 			$num = $this->db->num_rows($result);
@@ -511,13 +516,9 @@ class Notify
 								$object_type = 'propal';
 								$object_type = 'propal';
 								$labeltouse = $conf->global->PROPAL_CLOSE_REFUSED_TEMPLATE;
 								$labeltouse = $conf->global->PROPAL_CLOSE_REFUSED_TEMPLATE;
 								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedRefused", $link);
 								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedRefused", $link);
-								break;
-							case 'PROPAL_CLOSE_REFUSED_WEB':
-								$link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
-								$dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
-								$object_type = 'propal';
-								$labeltouse = $conf->global->PROPAL_CLOSE_REFUSED_TEMPLATE;
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedRefusedWeb", $link);
+								if (!empty($object->context['closedfromonlinesignature'])) {
+									$mesg .= ' - From online page';
+								}
 								break;
 								break;
 							case 'PROPAL_CLOSE_SIGNED':
 							case 'PROPAL_CLOSE_SIGNED':
 								$link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
 								$link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
@@ -525,13 +526,9 @@ class Notify
 								$object_type = 'propal';
 								$object_type = 'propal';
 								$labeltouse = $conf->global->PROPAL_CLOSE_SIGNED_TEMPLATE;
 								$labeltouse = $conf->global->PROPAL_CLOSE_SIGNED_TEMPLATE;
 								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
 								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
-								break;
-							case 'PROPAL_CLOSE_SIGNED_WEB':
-								$link = '<a href="'.$urlwithroot.'/comm/propal/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
-								$dir_output = $conf->propal->multidir_output[$object->entity]."/".get_exdir(0, 0, 0, 1, $object, 'propal');
-								$object_type = 'propal';
-								$labeltouse = $conf->global->PROPAL_CLOSE_SIGNED_TEMPLATE;
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link);
+								if (!empty($object->context['closedfromonlinesignature'])) {
+									$mesg .= ' - From online page';
+								}
 								break;
 								break;
 							case 'FICHINTER_ADD_CONTACT':
 							case 'FICHINTER_ADD_CONTACT':
 								$link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
 								$link = '<a href="'.$urlwithroot.'/fichinter/card.php?id='.$object->id.'&entity='.$object->entity.'">'.$newref.'</a>';
@@ -651,6 +648,23 @@ class Notify
 
 
 						$labeltouse = !empty($labeltouse) ? $labeltouse : '';
 						$labeltouse = !empty($labeltouse) ? $labeltouse : '';
 
 
+						// Replace keyword __SUPERVISOREMAIL__
+						if (preg_match('/__SUPERVISOREMAIL__/', $sendto)) {
+							$newval = '';
+							if ($user->fk_user > 0) {
+								$supervisoruser = new User($this->db);
+								$supervisoruser->fetch($user->fk_user);
+								if ($supervisoruser->email) {
+									$newval = trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>');
+								}
+							}
+							dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
+							$sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
+							$sendto = preg_replace('/,\s*,/', ',', $sendto); // in some case you can have $sendto like "email, __SUPERVISOREMAIL__ , otheremail" then you have "email,  , othermail" and it's not valid
+							$sendto = preg_replace('/^[\s,]+/', '', $sendto); // Clean start of string
+							$sendto = preg_replace('/[\s,]+$/', '', $sendto); // Clean end of string
+						}
+
 						$parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'outputlangs'=>$outputlangs, 'labeltouse'=>$labeltouse);
 						$parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'outputlangs'=>$outputlangs, 'labeltouse'=>$labeltouse);
 						if (!isset($action)) {
 						if (!isset($action)) {
 							$action = '';
 							$action = '';
@@ -721,6 +735,7 @@ class Notify
 		}
 		}
 
 
 		// Check notification using fixed email
 		// Check notification using fixed email
+		// TODO Move vars NOTIFICATION_FIXEDEMAIL into table llx_notify_def and inclulde the case into previous loop of sql result
 		if (!$error) {
 		if (!$error) {
 			foreach ($conf->global as $key => $val) {
 			foreach ($conf->global as $key => $val) {
 				$reg = array();
 				$reg = array();

+ 15 - 15
htdocs/core/modules/modPartnership.class.php

@@ -212,7 +212,7 @@ class modPartnership extends DolibarrModules
 
 
 		// Dictionaries
 		// Dictionaries
 		$this->dictionaries=array(
 		$this->dictionaries=array(
-			'langs'=>'partnership@partnership',
+			'langs'=>'partnership',
 			// List of tables we want to see into dictonnary editor
 			// List of tables we want to see into dictonnary editor
 			'tabname'=>array("c_partnership_type"),
 			'tabname'=>array("c_partnership_type"),
 			// Label of tables
 			// Label of tables
@@ -291,7 +291,7 @@ class modPartnership extends DolibarrModules
 		//     'leftmenu'=>'partnership',
 		//     'leftmenu'=>'partnership',
 		//     'url'=>'/partnership/partnership_list.php',
 		//     'url'=>'/partnership/partnership_list.php',
 		//     // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
 		//     // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-		//     'langs'=>'partnership@partnership',
+		//     'langs'=>'partnership',
 		//     'position'=>1100+$r,
 		//     'position'=>1100+$r,
 		//     // Define condition to show or hide menu entry. Use '$conf->partnership->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
 		//     // Define condition to show or hide menu entry. Use '$conf->partnership->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
 		//     'enabled'=>'$conf->partnership->enabled',
 		//     'enabled'=>'$conf->partnership->enabled',
@@ -349,18 +349,18 @@ class modPartnership extends DolibarrModules
 		$r = 1;
 		$r = 1;
 		/* BEGIN MODULEBUILDER EXPORT PARTNERSHIP */
 		/* BEGIN MODULEBUILDER EXPORT PARTNERSHIP */
 		/*
 		/*
-		$langs->load("partnership@partnership");
+		$langs->load("partnership");
 		$this->export_code[$r]=$this->rights_class.'_'.$r;
 		$this->export_code[$r]=$this->rights_class.'_'.$r;
 		$this->export_label[$r]='PartnershipLines';	// Translation key (used only if key ExportDataset_xxx_z not found)
 		$this->export_label[$r]='PartnershipLines';	// Translation key (used only if key ExportDataset_xxx_z not found)
-		$this->export_icon[$r]='partnership@partnership';
+		$this->export_icon[$r]='partnership';
 		// Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
 		// Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
-		$keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership@partnership';
+		$keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership';
 		include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
 		include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
 		//$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
 		//$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
 		//unset($this->export_fields_array[$r]['t.fieldtoremove']);
 		//unset($this->export_fields_array[$r]['t.fieldtoremove']);
 		//$keyforclass = 'PartnershipLine'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnershipline@partnership'; $keyforalias='tl';
 		//$keyforclass = 'PartnershipLine'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnershipline@partnership'; $keyforalias='tl';
 		//include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
 		//include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
-		$keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership@partnership';
+		$keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership';
 		include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
 		include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
 		//$keyforselect='partnershipline'; $keyforaliasextra='extraline'; $keyforelement='partnershipline@partnership';
 		//$keyforselect='partnershipline'; $keyforaliasextra='extraline'; $keyforelement='partnershipline@partnership';
 		//include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
 		//include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
@@ -380,13 +380,13 @@ class modPartnership extends DolibarrModules
 		$r = 1;
 		$r = 1;
 		/* BEGIN MODULEBUILDER IMPORT PARTNERSHIP */
 		/* BEGIN MODULEBUILDER IMPORT PARTNERSHIP */
 		/*
 		/*
-		 $langs->load("partnership@partnership");
+		 $langs->load("partnership");
 		 $this->export_code[$r]=$this->rights_class.'_'.$r;
 		 $this->export_code[$r]=$this->rights_class.'_'.$r;
 		 $this->export_label[$r]='PartnershipLines';	// Translation key (used only if key ExportDataset_xxx_z not found)
 		 $this->export_label[$r]='PartnershipLines';	// Translation key (used only if key ExportDataset_xxx_z not found)
-		 $this->export_icon[$r]='partnership@partnership';
-		 $keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership@partnership';
+		 $this->export_icon[$r]='partnership';
+		 $keyforclass = 'Partnership'; $keyforclassfile='/partnership/class/partnership.class.php'; $keyforelement='partnership';
 		 include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
 		 include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
-		 $keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership@partnership';
+		 $keyforselect='partnership'; $keyforaliasextra='extra'; $keyforelement='partnership';
 		 include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
 		 include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
 		 //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
 		 //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
 		 $this->export_sql_start[$r]='SELECT DISTINCT ';
 		 $this->export_sql_start[$r]='SELECT DISTINCT ';
@@ -417,11 +417,11 @@ class modPartnership extends DolibarrModules
 		// Create extrafields during init
 		// Create extrafields during init
 		//include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 		//include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 		//$extrafields = new ExtraFields($this->db);
 		//$extrafields = new ExtraFields($this->db);
-		//$result1=$extrafields->addExtraField('partnership_myattr1', "New Attr 1 label", 'boolean', 1,  3, 'thirdparty',   0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
-		//$result2=$extrafields->addExtraField('partnership_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project',      0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
-		//$result3=$extrafields->addExtraField('partnership_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
-		//$result4=$extrafields->addExtraField('partnership_myattr4', "New Attr 4 label", 'select',  1,  3, 'thirdparty',   0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
-		//$result5=$extrafields->addExtraField('partnership_myattr5', "New Attr 5 label", 'text',    1, 10, 'user',         0, 0, '', '', 1, '', 0, 0, '', '', 'partnership@partnership', '$conf->partnership->enabled');
+		//$result1=$extrafields->addExtraField('partnership_myattr1', "New Attr 1 label", 'boolean', 1,  3, 'thirdparty',   0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+		//$result2=$extrafields->addExtraField('partnership_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project',      0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+		//$result3=$extrafields->addExtraField('partnership_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+		//$result4=$extrafields->addExtraField('partnership_myattr4', "New Attr 4 label", 'select',  1,  3, 'thirdparty',   0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
+		//$result5=$extrafields->addExtraField('partnership_myattr5', "New Attr 5 label", 'text',    1, 10, 'user',         0, 0, '', '', 1, '', 0, 0, '', '', 'partnership', '$conf->partnership->enabled');
 
 
 		// Permissions
 		// Permissions
 		$this->remove($options);
 		$this->remove($options);

+ 4 - 1
htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php

@@ -75,7 +75,10 @@ class InterfaceWorkflowManager extends DolibarrTriggers
 			if (isModEnabled('commande') && !empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER)) {
 			if (isModEnabled('commande') && !empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER)) {
 				$object->fetchObjectLinked();
 				$object->fetchObjectLinked();
 				if (!empty($object->linkedObjectsIds['commande'])) {
 				if (!empty($object->linkedObjectsIds['commande'])) {
-					setEventMessages($langs->trans("OrderExists"), null, 'warnings');
+					if (empty($object->context['closedfromonlinesignature'])) {
+						$langs->load("orders");
+						setEventMessages($langs->trans("OrderExists"), null, 'warnings');
+					}
 					return $ret;
 					return $ret;
 				} else {
 				} else {
 					include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
 					include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';

+ 3 - 1
htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php

@@ -992,6 +992,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
 				$object->trackid = 'sub'.$object->id;
 				$object->trackid = 'sub'.$object->id;
 			} elseif (preg_match('/^MEMBER_/', $action)) {
 			} elseif (preg_match('/^MEMBER_/', $action)) {
 				$object->trackid = 'mem'.$object->id;
 				$object->trackid = 'mem'.$object->id;
+			} elseif (preg_match('/^PARTNERSHIP_/', $action)) {
+				$object->trackid = 'pship'.$object->id;
 			} elseif (preg_match('/^PROJECT_/', $action)) {
 			} elseif (preg_match('/^PROJECT_/', $action)) {
 				$object->trackid = 'proj'.$object->id;
 				$object->trackid = 'proj'.$object->id;
 			} elseif (preg_match('/^TASK_/', $action)) {
 			} elseif (preg_match('/^TASK_/', $action)) {
@@ -1090,7 +1092,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
 			$actioncomm->errors_to     = empty($object->errors_to) ? null : $object->errors_to;
 			$actioncomm->errors_to     = empty($object->errors_to) ? null : $object->errors_to;
 		}
 		}
 
 
-		// Object linked (if link is for thirdparty, contact, project it is a recording error. We should not have links in link table
+		// Object linked (if link is for thirdparty, contact or project, it is a recording error. We should not have links in link table
 		// for such objects because there is already a dedicated field into table llx_actioncomm or llx_actioncomm_resources.
 		// for such objects because there is already a dedicated field into table llx_actioncomm or llx_actioncomm_resources.
 		if (!in_array($elementtype, array('societe', 'contact', 'project'))) {
 		if (!in_array($elementtype, array('societe', 'contact', 'project'))) {
 			$actioncomm->fk_element  = $elementid;
 			$actioncomm->fk_element  = $elementid;

+ 4 - 3
htdocs/core/triggers/interface_50_modNotification_Notification.class.php

@@ -45,7 +45,7 @@ class InterfaceNotification extends DolibarrTriggers
 
 
 		$this->name = preg_replace('/^Interface/i', '', get_class($this));
 		$this->name = preg_replace('/^Interface/i', '', get_class($this));
 		$this->family = "notification";
 		$this->family = "notification";
-		$this->description = "Triggers of this module send email notifications according to Notification module setup.";
+		$this->description = "Triggers of this module send Email notifications according to Notification module setup.";
 		// 'development', 'experimental', 'dolibarr' or version
 		// 'development', 'experimental', 'dolibarr' or version
 		$this->version = self::VERSION_DOLIBARR;
 		$this->version = self::VERSION_DOLIBARR;
 		$this->picto = 'email';
 		$this->picto = 'email';
@@ -70,6 +70,7 @@ class InterfaceNotification extends DolibarrTriggers
 			return 0; // Module not active, we do nothing
 			return 0; // Module not active, we do nothing
 		}
 		}
 
 
+		// If the trigger code is not managed by the Notification module
 		if (!in_array($action, $this->listofmanagedevents)) {
 		if (!in_array($action, $this->listofmanagedevents)) {
 			return 0;
 			return 0;
 		}
 		}
@@ -112,7 +113,7 @@ class InterfaceNotification extends DolibarrTriggers
 		$ret = array();
 		$ret = array();
 
 
 
 
-		$sql = "SELECT rowid, code, label, description, elementtype";
+		$sql = "SELECT rowid, code, contexts, label, description, elementtype";
 		$sql .= " FROM ".MAIN_DB_PREFIX."c_action_trigger";
 		$sql .= " FROM ".MAIN_DB_PREFIX."c_action_trigger";
 		$sql .= $this->db->order("rang, elementtype, code");
 		$sql .= $this->db->order("rang, elementtype, code");
 
 
@@ -153,7 +154,7 @@ class InterfaceNotification extends DolibarrTriggers
 				}
 				}
 
 
 				if ($qualified) {
 				if ($qualified) {
-					$ret[] = array('rowid'=>$obj->rowid, 'code'=>$obj->code, 'label'=>$obj->label, 'description'=>$obj->description, 'elementtype'=>$obj->elementtype);
+					$ret[] = array('rowid'=>$obj->rowid, 'code'=>$obj->code, 'contexts'=>$obj->contexts, 'label'=>$obj->label, 'description'=>$obj->description, 'elementtype'=>$obj->elementtype);
 				}
 				}
 
 
 				$i++;
 				$i++;

+ 4 - 4
htdocs/core/website.inc.php

@@ -117,8 +117,8 @@ if (!defined('USEDOLIBARRSERVER') && !defined('USEDOLIBARREDITOR')) {
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		//
 		//
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com;";
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
 		$contentsecuritypolicy = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCECSPRO');
 		$contentsecuritypolicy = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCECSPRO');
 
 
 		if (!is_object($hookmanager)) {
 		if (!is_object($hookmanager)) {
@@ -149,8 +149,8 @@ if (!defined('USEDOLIBARRSERVER') && !defined('USEDOLIBARREDITOR')) {
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		//
 		//
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com;";
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
 		$contentsecuritypolicy = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCECSP');
 		$contentsecuritypolicy = getDolGlobalString('WEBSITE_MAIN_SECURITY_FORCECSP');
 
 
 		if (!is_object($hookmanager)) {
 		if (!is_object($hookmanager)) {

+ 1 - 1
htdocs/includes/tcpdi/tcpdi.php

@@ -333,7 +333,7 @@ class TCPDI extends FPDF_TPL {
                             break;
                             break;
                     }
                     }
                 }
                 }
-            } elseif ($tpl['x'] != 0 || $tpl['y'] != 0) {
+            } elseif (!empty($tpl['x']) || !empty($tpl['y'])) {
                 $tx = -$tpl['x'] * 2;
                 $tx = -$tpl['x'] * 2;
                 $ty = $tpl['y'] * 2;
                 $ty = $tpl['y'] * 2;
             }
             }

+ 9 - 2
htdocs/install/mysql/data/llx_c_action_trigger.sql

@@ -43,9 +43,7 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_MODIFY','Customer proposal modified','Executed when a customer proposal is modified','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_MODIFY','Customer proposal modified','Executed when a customer proposal is modified','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_SENTBYMAIL','Commercial proposal sent by mail','Executed when a commercial proposal is sent by mail','propal',3);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_SENTBYMAIL','Commercial proposal sent by mail','Executed when a commercial proposal is sent by mail','propal',3);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED','Customer proposal closed signed','Executed when a customer proposal is closed signed','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED','Customer proposal closed signed','Executed when a customer proposal is closed signed','propal',2);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED_WEB','Customer proposal closed signed on portal','Executed when a customer proposal is closed signed on portal','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED','Customer proposal closed refused','Executed when a customer proposal is closed refused','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED','Customer proposal closed refused','Executed when a customer proposal is closed refused','propal',2);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED_WEB','Customer proposal closed refused on portal','Executed when a customer proposal is closed refused on portal','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLASSIFY_BILLED','Customer proposal set billed','Executed when a customer proposal is set to billed','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLASSIFY_BILLED','Customer proposal set billed','Executed when a customer proposal is set to billed','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_DELETE','Customer proposal deleted','Executed when a customer proposal is deleted','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_DELETE','Customer proposal deleted','Executed when a customer proposal is deleted','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_VALIDATE','Customer order validate','Executed when a customer order is validated','commande',4);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_VALIDATE','Customer order validate','Executed when a customer order is validated','commande',4);
@@ -153,6 +151,8 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_MODIFY','Contact address update','Executed when a contact is updated','contact',51);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_MODIFY','Contact address update','Executed when a contact is updated','contact',51);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_SENTBYMAIL','Mails sent from third party card','Executed when you send email from contact address record','contact',52);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_SENTBYMAIL','Mails sent from third party card','Executed when you send email from contact address record','contact',52);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_DELETE','Contact address deleted','Executed when a contact is deleted','contact',53);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_DELETE','Contact address deleted','Executed when a contact is deleted','contact',53);
+
+-- recruitment module
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_CREATE','Job created','Executed when a job is created','recruitment',7500);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_CREATE','Job created','Executed when a job is created','recruitment',7500);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_MODIFY','Job modified','Executed when a job is modified','recruitment',7502);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_MODIFY','Job modified','Executed when a job is modified','recruitment',7502);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_SENTBYMAIL','Mails sent from job record','Executed when you send email from job record','recruitment',7504);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECRUITMENTJOBPOSITION_SENTBYMAIL','Mails sent from job record','Executed when you send email from job record','recruitment',7504);
@@ -181,3 +181,10 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_MODIFY','Template invoices update','Executed when a Template invoices is updated','facturerec',901);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_MODIFY','Template invoices update','Executed when a Template invoices is updated','facturerec',901);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_DELETE','Template invoices deleted','Executed when a Template invoices is deleted','facturerec',902);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_DELETE','Template invoices deleted','Executed when a Template invoices is deleted','facturerec',902);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_AUTOCREATEBILL','Template invoices use to create invoices with auto batch','Executed when a Template invoices is use to create invoice with auto batch','facturerec',903);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILLREC_AUTOCREATEBILL','Template invoices use to create invoices with auto batch','Executed when a Template invoices is use to create invoice with auto batch','facturerec',903);
+
+-- partnership module
+insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_CREATE','Partnership created','Executed when a partnership is created','partnership',58000);
+insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_MODIFY','Partnership modified','Executed when a partnership is modified','partnership',58002);
+insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_SENTBYMAIL','Mails sent from partnership file','Executed when you send email from partnership file','partnership',58004);
+insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PARTNERSHIP_DELETE','Partnership deleted','Executed when a partnership is deleted','partnership',58006);
+

+ 1 - 2
htdocs/install/mysql/migration/16.0.0-17.0.0.sql

@@ -64,6 +64,7 @@ ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_percent (percent);
 
 
 UPDATE llx_c_paiement SET code = 'BANCON' WHERE code = 'BAN' AND libelle = 'Bancontact';
 UPDATE llx_c_paiement SET code = 'BANCON' WHERE code = 'BAN' AND libelle = 'Bancontact';
 
 
+ALTER TABLE llx_partnership DROP FOREIGN KEY llx_partnership_fk_user_creat;
 -- VMYSQL4.3 ALTER TABLE llx_partnership MODIFY COLUMN fk_user_creat integer NULL;
 -- VMYSQL4.3 ALTER TABLE llx_partnership MODIFY COLUMN fk_user_creat integer NULL;
 -- VPGSQL8.2 ALTER TABLE llx_partnership ALTER COLUMN fk_user_creat DROP NOT NULL;
 -- VPGSQL8.2 ALTER TABLE llx_partnership ALTER COLUMN fk_user_creat DROP NOT NULL;
 
 
@@ -241,9 +242,7 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_MODIFY','Customer proposal modified','Executed when a customer proposal is modified','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_MODIFY','Customer proposal modified','Executed when a customer proposal is modified','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_SENTBYMAIL','Commercial proposal sent by mail','Executed when a commercial proposal is sent by mail','propal',3);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_SENTBYMAIL','Commercial proposal sent by mail','Executed when a commercial proposal is sent by mail','propal',3);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED','Customer proposal closed signed','Executed when a customer proposal is closed signed','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED','Customer proposal closed signed','Executed when a customer proposal is closed signed','propal',2);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED_WEB','Customer proposal closed signed on portal','Executed when a customer proposal is closed signed on portal','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED','Customer proposal closed refused','Executed when a customer proposal is closed refused','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED','Customer proposal closed refused','Executed when a customer proposal is closed refused','propal',2);
-insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED_WEB','Customer proposal closed refused on portal','Executed when a customer proposal is closed refused on portal','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLASSIFY_BILLED','Customer proposal set billed','Executed when a customer proposal is set to billed','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLASSIFY_BILLED','Customer proposal set billed','Executed when a customer proposal is set to billed','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_DELETE','Customer proposal deleted','Executed when a customer proposal is deleted','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_DELETE','Customer proposal deleted','Executed when a customer proposal is deleted','propal',2);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_VALIDATE','Customer order validate','Executed when a customer order is validated','commande',4);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_VALIDATE','Customer order validate','Executed when a customer order is validated','commande',4);

+ 6 - 0
htdocs/install/mysql/migration/17.0.0-18.0.0.sql

@@ -45,6 +45,12 @@ ALTER TABLE llx_facture_fourn_det MODIFY COLUMN ref varchar(128);
 
 
 -- v18
 -- v18
 
 
+ALTER TABLE llx_notify_def ADD COLUMN email varchar(255);
+ALTER TABLE llx_notify_def ADD COLUMN threshold double(24,8);
+ALTER TABLE llx_notify_def ADD COLUMN context varchar(128);
+
+ALTER TABLE llx_c_action_trigger ADD COLUMN contexts varchar(255) NULL;
+
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_CLOSE','Project closed','Executed when a project is closed','project',145);
 insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_CLOSE','Project closed','Executed when a project is closed','project',145);
 
 
 -- amount was removed in v12
 -- amount was removed in v12

+ 1 - 0
htdocs/install/mysql/tables/llx_c_action_trigger.sql

@@ -24,6 +24,7 @@ create table llx_c_action_trigger
   rowid			integer AUTO_INCREMENT PRIMARY KEY,
   rowid			integer AUTO_INCREMENT PRIMARY KEY,
   elementtype	varchar(64) 			NOT NULL,
   elementtype	varchar(64) 			NOT NULL,
   code			varchar(128)			NOT NULL,
   code			varchar(128)			NOT NULL,
+  contexts		varchar(255)			NULL,			-- list of possible contexts when ther is different context of trigger
   label			varchar(128)			NOT NULL,
   label			varchar(128)			NOT NULL,
   description	varchar(255),
   description	varchar(255),
   rang			integer		DEFAULT 0
   rang			integer		DEFAULT 0

+ 3 - 0
htdocs/install/mysql/tables/llx_notify_def.sql

@@ -27,5 +27,8 @@ create table llx_notify_def
   fk_soc          integer,
   fk_soc          integer,
   fk_contact      integer,
   fk_contact      integer,
   fk_user		  integer,
   fk_user		  integer,
+  email           varchar(255),          -- for fixed email notif
+  threshold       double(24,8),          -- threshold on an amount to qualify the notification
+  context         varchar(128),          -- only for a particular contet
   type            varchar(16) DEFAULT 'email'	-- 'browser', 'email', 'sms', 'webservice', ...
   type            varchar(16) DEFAULT 'email'	-- 'browser', 'email', 'sms', 'webservice', ...
 )ENGINE=innodb;
 )ENGINE=innodb;

+ 0 - 2
htdocs/langs/en_US/other.lang

@@ -46,9 +46,7 @@ Notify_ORDER_SUPPLIER_APPROVE=Purchase order approved
 Notify_ORDER_SUPPLIER_REFUSE=Purchase order refused
 Notify_ORDER_SUPPLIER_REFUSE=Purchase order refused
 Notify_PROPAL_VALIDATE=Customer proposal validated
 Notify_PROPAL_VALIDATE=Customer proposal validated
 Notify_PROPAL_CLOSE_SIGNED=Customer proposal closed signed
 Notify_PROPAL_CLOSE_SIGNED=Customer proposal closed signed
-Notify_PROPAL_CLOSE_SIGNED_WEB=Customer proposal closed signed on portal page
 Notify_PROPAL_CLOSE_REFUSED=Customer proposal closed refused
 Notify_PROPAL_CLOSE_REFUSED=Customer proposal closed refused
-Notify_PROPAL_CLOSE_REFUSED_WEB=Customer proposal closed refused on portal page
 Notify_PROPAL_SENTBYMAIL=Commercial proposal sent by mail
 Notify_PROPAL_SENTBYMAIL=Commercial proposal sent by mail
 Notify_WITHDRAW_TRANSMIT=Transmission withdrawal
 Notify_WITHDRAW_TRANSMIT=Transmission withdrawal
 Notify_WITHDRAW_CREDIT=Credit withdrawal
 Notify_WITHDRAW_CREDIT=Credit withdrawal

+ 1 - 0
htdocs/langs/en_US/partnership.lang

@@ -93,4 +93,5 @@ ReasonDeclineOrCancel=Reason for declining or canceling
 
 
 NewPartnershipRequest=New partnership request
 NewPartnershipRequest=New partnership request
 NewPartnershipRequestDesc=This form allows you to request to be part of one of our partnership program. If you need help to fill this form, please contact by email <b>%s</b>.
 NewPartnershipRequestDesc=This form allows you to request to be part of one of our partnership program. If you need help to fill this form, please contact by email <b>%s</b>.
+ThisUrlMustContainsAtLeastOneLinkToWebsite=This page must contains at least one link to one of the following domain: %s 
 
 

+ 4 - 4
htdocs/main.inc.php

@@ -1504,8 +1504,8 @@ function top_httphead($contenttype = 'text/html', $forcenocache = 0)
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		//
 		//
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com;";
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
 		$contentsecuritypolicy = getDolGlobalString('MAIN_SECURITY_FORCECSPRO');
 		$contentsecuritypolicy = getDolGlobalString('MAIN_SECURITY_FORCECSPRO');
 
 
 		if (!is_object($hookmanager)) {
 		if (!is_object($hookmanager)) {
@@ -1541,8 +1541,8 @@ function top_httphead($contenttype = 'text/html', $forcenocache = 0)
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// Pre-existing site that uses too much js code to fix but wants to ensure resources are loaded only over https and disable plugins:
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		// default-src https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'
 		//
 		//
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com;";
-		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googlapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
+		// $contentsecuritypolicy = "frame-ancestors 'self'; img-src * data:; font-src *; default-src *; script-src 'self' 'unsafe-inline' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com; style-src 'self' 'unsafe-inline'; connect-src 'self';";
 		$contentsecuritypolicy = getDolGlobalString('MAIN_SECURITY_FORCECSP');
 		$contentsecuritypolicy = getDolGlobalString('MAIN_SECURITY_FORCECSP');
 
 
 		if (!is_object($hookmanager)) {
 		if (!is_object($hookmanager)) {

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

@@ -521,7 +521,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 		if (empty($reshook)) {
 		if (empty($reshook)) {
 			// Send
 			// Send
 			if (empty($user->socid)) {
 			if (empty($user->socid)) {
-				print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init&token='.newToken().'#formmailbeforetitle');
+				print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle');
 			}
 			}
 
 
 			// Back to draft
 			// Back to draft

+ 0 - 74
htdocs/partnership/admin/about.php

@@ -1,74 +0,0 @@
-<?php
-/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2021 Dorian Laurent <i.merraha@sofimedmaroc.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    partnership/admin/about.php
- * \ingroup partnership
- * \brief   About page of module Partnership.
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-require_once '../lib/partnership.lib.php';
-
-// Translations
-$langs->loadLangs(array("errors", "admin", "partnership@partnership"));
-
-// Access control
-if (!$user->admin) {
-	accessforbidden();
-}
-
-// Parameters
-$action = GETPOST('action', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-
-/*
- * Actions
- */
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$page_name = "PartnershipAbout";
-llxHeader('', $langs->trans($page_name));
-
-// Subheader
-$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
-
-print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup');
-
-// Configuration header
-$head = partnershipAdminPrepareHead();
-print dol_get_fiche_head($head, 'about', '', 0, 'partnership@partnership');
-
-require_once DOL_DOCUMENT_ROOT.'/core/modules/modPartnership.class.php';
-$tmpmodule = new modPartnership($db);
-print $tmpmodule->getDescLong();
-
-// Page end
-print dol_get_fiche_end();
-llxFooter();
-$db->close();

+ 3 - 0
htdocs/partnership/class/partnership.class.php

@@ -555,6 +555,9 @@ class Partnership extends CommonObject
 			$this->error[] = "ErrorThirpdartyOrMemberidIsMandatory";
 			$this->error[] = "ErrorThirpdartyOrMemberidIsMandatory";
 			return -1;
 			return -1;
 		}
 		}
+		if (empty($this->fk_user_creat)) {	// For the case the object was created with empty user (from public page).
+			$this->fk_user_creat = $user->id;
+		}
 
 
 		return $this->updateCommon($user, $notrigger);
 		return $this->updateCommon($user, $notrigger);
 	}
 	}

+ 53 - 47
htdocs/partnership/partnership_card.php

@@ -39,10 +39,11 @@ $ref = GETPOST('ref', 'alpha');
 $action = GETPOST('action', 'aZ09');
 $action = GETPOST('action', 'aZ09');
 $confirm = GETPOST('confirm', 'alpha');
 $confirm = GETPOST('confirm', 'alpha');
 $cancel = GETPOST('cancel', 'aZ09');
 $cancel = GETPOST('cancel', 'aZ09');
-$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'partnershipcard'; // To manage different context of search
+$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
 $backtopage = GETPOST('backtopage', 'alpha');
 $backtopage = GETPOST('backtopage', 'alpha');
 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
 $lineid   = GETPOST('lineid', 'int');
 $lineid   = GETPOST('lineid', 'int');
+$dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09');
 
 
 // Initialize technical objects
 // Initialize technical objects
 $object = new Partnership($db);
 $object = new Partnership($db);
@@ -73,20 +74,25 @@ if (empty($action) && empty($id) && empty($ref)) {
 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
 
 
 
 
-$permissiontoread 		= $user->rights->partnership->read;
-$permissiontoadd 		= $user->rights->partnership->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
-$permissiontodelete 	= $user->rights->partnership->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
-$permissionnote 		= $user->rights->partnership->write; // Used by the include of actions_setnotes.inc.php
-$permissiondellink 		= $user->rights->partnership->write; // Used by the include of actions_dellink.inc.php
+$permissiontoread 		= $user->hasRight('partnership', 'read');
+$permissiontoadd 		= $user->hasRight('partnership', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
+$permissiontodelete 	= $user->hasRight('partnership', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
+$permissionnote 		= $user->hasRight('partnership', 'write'); // Used by the include of actions_setnotes.inc.php
+$permissiondellink 		= $user->hasRight('partnership', 'write'); // Used by the include of actions_dellink.inc.php
 $upload_dir 			= $conf->partnership->multidir_output[isset($object->entity) ? $object->entity : 1];
 $upload_dir 			= $conf->partnership->multidir_output[isset($object->entity) ? $object->entity : 1];
 $managedfor 			= getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR', 'thirdparty');
 $managedfor 			= getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR', 'thirdparty');
 
 
-// Security check - Protection if external user
+// Security check (enable the most restrictive one)
 //if ($user->socid > 0) accessforbidden();
 //if ($user->socid > 0) accessforbidden();
 //if ($user->socid > 0) $socid = $user->socid;
 //if ($user->socid > 0) $socid = $user->socid;
-//$result = restrictedArea($user, 'partnership', $object->id);
-if (empty($conf->partnership->enabled)) accessforbidden();
-if (empty($permissiontoread)) accessforbidden();
+//$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0);
+//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
+if (!isModEnabled('partnership')) {
+	accessforbidden();
+}
+if (!$permissiontoread) {
+	accessforbidden();
+}
 if ($object->id > 0 && !($object->fk_member > 0) && $managedfor == 'member') accessforbidden();
 if ($object->id > 0 && !($object->fk_member > 0) && $managedfor == 'member') accessforbidden();
 if ($object->id > 0 && !($object->fk_soc > 0) && $managedfor == 'thirdparty') accessforbidden();
 if ($object->id > 0 && !($object->fk_soc > 0) && $managedfor == 'thirdparty') accessforbidden();
 
 
@@ -119,11 +125,11 @@ if (empty($reshook)) {
 	$fk_partner 	= ($managedfor == 'member') ? GETPOST('fk_member', 'int') : GETPOST('fk_soc', 'int');
 	$fk_partner 	= ($managedfor == 'member') ? GETPOST('fk_member', 'int') : GETPOST('fk_soc', 'int');
 	$obj_partner 	= ($managedfor == 'member') ? $object->fk_member : $object->fk_soc;
 	$obj_partner 	= ($managedfor == 'member') ? $object->fk_member : $object->fk_soc;
 
 
+	$triggermodname = 'PARTNERSHIP_MODIFY'; // Name of trigger action code to execute when we modify record
+
 	// Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
 	// Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
 	include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
 	include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
 
 
-	$triggermodname = 'PARTNERSHIP_MODIFY'; // Name of trigger action code to execute when we modify record
-
 	// Action accept object
 	// Action accept object
 	if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) {
 	if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) {
 		$result = $object->validate($user);
 		$result = $object->validate($user);
@@ -264,6 +270,10 @@ llxHeader('', $title, $help_url);
 
 
 // Part to create
 // Part to create
 if ($action == 'create') {
 if ($action == 'create') {
+	if (empty($permissiontoadd)) {
+		accessforbidden('NotEnoughPermissions', 0, 1);
+	}
+
 	print load_fiche_titre($langs->trans("NewPartnership"), '', 'object_'.$object->picto);
 	print load_fiche_titre($langs->trans("NewPartnership"), '', 'object_'.$object->picto);
 
 
 	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
 	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
@@ -333,9 +343,8 @@ if (($id || $ref) && $action == 'edit') {
 
 
 // Part to show record
 // Part to show record
 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
-	$res = $object->fetch_optionals();
-
 	$head = partnershipPrepareHead($object);
 	$head = partnershipPrepareHead($object);
+
 	print dol_get_fiche_head($head, 'card', $langs->trans("Partnership"), -1, $object->picto);
 	print dol_get_fiche_head($head, 'card', $langs->trans("Partnership"), -1, $object->picto);
 
 
 	$formconfirm = '';
 	$formconfirm = '';
@@ -405,38 +414,35 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 	$morehtmlref = '<div class="refidno">';
 	$morehtmlref = '<div class="refidno">';
 	/*
 	/*
 	 // Ref customer
 	 // 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);
+	 $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
 	 // Thirdparty
-	 $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
+		$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'customer');
+		if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) {
+			$morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
+		}
 	 // Project
 	 // 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, 0, 1, '', 'maxwidth300');
-	 $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, '', 'maxwidth300');
-	 }
-	 } else {
-	 if (!empty($object->fk_project)) {
-	 $proj = new Project($db);
-	 $proj->fetch($object->fk_project);
-	 $morehtmlref .= ': '.$proj->getNomUrl();
-	 } else {
-	 $morehtmlref .= '';
-	 }
-	 }
-	 }*/
+		if (isModEnabled('project')) {
+			$langs->load("projects");
+			$morehtmlref .= '<br>';
+			if ($permissiontoadd) {
+				$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
+				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 .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
+			} else {
+				if (!empty($object->fk_project)) {
+					$proj = new Project($db);
+					$proj->fetch($object->fk_project);
+					$morehtmlref .= $proj->getNomUrl(1);
+					if ($proj->title) {
+						$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
+					}
+				}
+			}
+		}
+	*/
 	$morehtmlref .= '</div>';
 	$morehtmlref .= '</div>';
 	if (!isset($npfilter)) {
 	if (!isset($npfilter)) {
 		$npfilter = "";
 		$npfilter = "";
@@ -632,8 +638,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 			$relativepath = $objref.'/'.$objref.'.pdf';
 			$relativepath = $objref.'/'.$objref.'.pdf';
 			$filedir = $conf->partnership->dir_output.'/'.$object->element.'/'.$objref;
 			$filedir = $conf->partnership->dir_output.'/'.$object->element.'/'.$objref;
 			$urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
 			$urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
-			$genallowed = $user->rights->partnership->read; // If you can read, you can build the PDF to read content
-			$delallowed = $user->rights->partnership->write; // If you can create/edit, you can remove a file on card
+			$genallowed = $permissiontoread; // If you can read, you can build the PDF to read content
+			$delallowed = $permissiontoadd; // If you can create/edit, you can remove a file on card
 			print $formfile->showdocuments('partnership:Partnership', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
 			print $formfile->showdocuments('partnership:Partnership', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
 		}
 		}
 
 
@@ -651,7 +657,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 		// List of actions on element
 		// List of actions on element
 		include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
 		include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
 		$formactions = new FormActions($db);
 		$formactions = new FormActions($db);
-		$somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
+		$somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
 
 
 		print '</div></div>';
 		print '</div></div>';
 	}
 	}

+ 3 - 4
htdocs/public/onlinesign/newonlinesign.php

@@ -160,6 +160,9 @@ if ($source == 'proposal') {
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
 $hookmanager->initHooks(array('onlinesign'));
 $hookmanager->initHooks(array('onlinesign'));
 
 
+$error = 0;
+
+
 /*
 /*
  * Actions
  * Actions
  */
  */
@@ -191,10 +194,6 @@ if ($action == 'confirm_refusepropal' && $confirm == 'yes') {
 			if ($result < 0) {
 			if ($result < 0) {
 				$error++;
 				$error++;
 			}
 			}
-			$result = $object->call_trigger('PROPAL_CLOSE_REFUSED_WEB', $user);
-			if ($result < 0) {
-				$error++;
-			}
 		}
 		}
 	} else {
 	} else {
 		$db->rollback();
 		$db->rollback();

+ 19 - 0
htdocs/public/partnership/new.php

@@ -270,6 +270,7 @@ if (empty($reshook) && $action == 'add') {
 				$company->zip         = GETPOST('zipcode');
 				$company->zip         = GETPOST('zipcode');
 				$company->town        = GETPOST('town');
 				$company->town        = GETPOST('town');
 				$company->email       = GETPOST('email');
 				$company->email       = GETPOST('email');
+				$company->url         = GETPOST('url');
 				$company->country_id  = GETPOST('country_id', 'int');
 				$company->country_id  = GETPOST('country_id', 'int');
 				$company->state_id    = GETPOST('state_id', 'int');
 				$company->state_id    = GETPOST('state_id', 'int');
 				$company->name_alias  = dolGetFirstLastname(GETPOST('firstname'), GETPOST('lastname'));
 				$company->name_alias  = dolGetFirstLastname(GETPOST('firstname'), GETPOST('lastname'));
@@ -303,12 +304,16 @@ if (empty($reshook) && $action == 'add') {
 			if (empty($company->email)) {
 			if (empty($company->email)) {
 				$company->email = GETPOST('email');
 				$company->email = GETPOST('email');
 			}
 			}
+			if (empty($company->url)) {
+				$company->url = GETPOST('url');
+			}
 			if (empty($company->state_id)) {
 			if (empty($company->state_id)) {
 				$company->state_id = GETPOST('state_id', 'int');
 				$company->state_id = GETPOST('state_id', 'int');
 			}
 			}
 			if (empty($company->name_alias)) {
 			if (empty($company->name_alias)) {
 				$company->name_alias = dolGetFirstLastname(GETPOST('firstname'), GETPOST('lastname'));
 				$company->name_alias = dolGetFirstLastname(GETPOST('firstname'), GETPOST('lastname'));
 			}
 			}
+
 			$company->update(0);
 			$company->update(0);
 		}
 		}
 
 
@@ -617,6 +622,20 @@ print '<tr><td class="classfortooltip" title="'.dol_escape_htmltag($messagemanda
 print '<tr><td class="classfortooltip" title="'.dol_escape_htmltag($messagemandatory).'">'.$langs->trans("Email").' <span class="star">*</span></td><td>';
 print '<tr><td class="classfortooltip" title="'.dol_escape_htmltag($messagemandatory).'">'.$langs->trans("Email").' <span class="star">*</span></td><td>';
 //print img_picto('', 'email', 'class="pictofixedwidth"');
 //print img_picto('', 'email', 'class="pictofixedwidth"');
 print '<input type="text" name="email" maxlength="255" class="minwidth200" value="'.dol_escape_htmltag(GETPOST('email')).'"></td></tr>'."\n";
 print '<input type="text" name="email" maxlength="255" class="minwidth200" value="'.dol_escape_htmltag(GETPOST('email')).'"></td></tr>'."\n";
+// Url
+print '<tr><td>'.$langs->trans("Url").' <span style="color:red;">*</span></td><td>';
+print '<input type="text" name="url" maxlength="255" class="minwidth200" value="'.dol_escape_htmltag(GETPOST('url')).'">';
+if (getDolGlobalString('PARTNERSHIP_BACKLINKS_TO_CHECK')) {
+	$listofkeytocheck = explode('|', getDolGlobalString('PARTNERSHIP_BACKLINKS_TO_CHECK'));
+	$i = 0;
+	$s = '';
+	foreach ($listofkeytocheck as $val) {
+		$i++;
+		$s .= ($s ? ($i == count($listofkeytocheck) ? ' '.$langs->trans("or").' ' : ', ') : '').$val;
+	}
+	print '<br><span class="opacitymedium small">'.$langs->trans("ThisUrlMustContainsAtLeastOneLinkToWebsite", $s).'</small>';
+}
+print '</td></tr>'."\n";
 // Address
 // Address
 print '<tr><td>'.$langs->trans("Address").'</td><td>'."\n";
 print '<tr><td>'.$langs->trans("Address").'</td><td>'."\n";
 print '<textarea name="address" id="address" wrap="soft" class="quatrevingtpercent" rows="'.ROWS_3.'">'.dol_escape_htmltag(GETPOST('address', 'restricthtml'), 0, 1).'</textarea></td></tr>'."\n";
 print '<textarea name="address" id="address" wrap="soft" class="quatrevingtpercent" rows="'.ROWS_3.'">'.dol_escape_htmltag(GETPOST('address', 'restricthtml'), 0, 1).'</textarea></td></tr>'."\n";

+ 3 - 0
htdocs/ticket/agenda.php

@@ -46,6 +46,9 @@ $track_id = GETPOST('track_id', 'alpha', 3);
 $socid    = GETPOST('socid', 'int');
 $socid    = GETPOST('socid', 'int');
 $action   = GETPOST('action', 'aZ09');
 $action   = GETPOST('action', 'aZ09');
 
 
+// Store current page url
+$url_page_current = DOL_URL_ROOT.'/ticket/agenda.php';
+
 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
 $sortfield = GETPOST('sortfield', 'aZ09comma');
 $sortfield = GETPOST('sortfield', 'aZ09comma');
 $sortorder = GETPOST('sortorder', 'aZ09comma');
 $sortorder = GETPOST('sortorder', 'aZ09comma');

+ 1 - 1
htdocs/ticket/contact.php

@@ -252,7 +252,7 @@ if ($id > 0 || !empty($track_id) || !empty($ref)) {
 
 
 		$linkback = '<a href="'.dol_buildpath('/ticket/list.php', 1).'"><strong>'.$langs->trans("BackToList").'</strong></a> ';
 		$linkback = '<a href="'.dol_buildpath('/ticket/list.php', 1).'"><strong>'.$langs->trans("BackToList").'</strong></a> ';
 
 
-		dol_banner_tab($object, 'ref', $linkback, ($user->socid ? 0 : 1), 'ref', 'ref', $morehtmlref, '', 0, '', '', 1, '');
+		dol_banner_tab($object, 'ref', $linkback, (empty($user->socid) ? 1 : 0), 'ref', 'ref', $morehtmlref, '', 0, '', '', 1, '');
 
 
 		print dol_get_fiche_end();
 		print dol_get_fiche_end();
 
 

+ 3 - 0
htdocs/ticket/document.php

@@ -49,6 +49,9 @@ $track_id = GETPOST('track_id', 'alpha');
 $action   = GETPOST('action', 'alpha');
 $action   = GETPOST('action', 'alpha');
 $confirm  = GETPOST('confirm', 'alpha');
 $confirm  = GETPOST('confirm', 'alpha');
 
 
+// Store current page url
+$url_page_current = DOL_URL_ROOT.'/ticket/document.php';
+
 // Get parameters
 // Get parameters
 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
 $sortfield = GETPOST('sortfield', 'aZ09comma');
 $sortfield = GETPOST('sortfield', 'aZ09comma');

+ 3 - 0
htdocs/ticket/messaging.php

@@ -46,6 +46,9 @@ $track_id = GETPOST('track_id', 'alpha', 3);
 $socid    = GETPOST('socid', 'int');
 $socid    = GETPOST('socid', 'int');
 $action   = GETPOST('action', 'aZ09');
 $action   = GETPOST('action', 'aZ09');
 
 
+// Store current page url
+$url_page_current = DOL_URL_ROOT.'/ticket/messaging.php';
+
 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
 $sortfield = GETPOST("sortfield", "aZ09comma");
 $sortfield = GETPOST("sortfield", "aZ09comma");
 $sortorder = GETPOST("sortorder", 'aZ09comma');
 $sortorder = GETPOST("sortorder", 'aZ09comma');