Passed
Push — master ( 853f8f...c34860 )
by Alxarafe
25:12
created
dolibarr/htdocs/core/class/CMailFile.class.php 1 patch
Indentation   +1425 added lines, -1425 removed lines patch added patch discarded remove patch
@@ -36,323 +36,323 @@  discard block
 block discarded – undo
36 36
  */
37 37
 class CMailFile
38 38
 {
39
-	public $sendcontext;
40
-	public $sendmode;
41
-	public $sendsetup;
42
-
43
-	var $subject;      	// Topic:       Subject of email
44
-	var $addr_from;    	// From:		Label and EMail of sender (must include '<>'). For example '<[email protected]>' or 'John Doe <[email protected]>' or '<[email protected]>'). Note that with gmail smtps, value here is forced by google to account (but not the reply-to).
45
-	// Sender:      Who send the email ("Sender" has sent emails on behalf of "From").
46
-	//              Use it when the "From" is an email of a domain that is a SPF protected domain, and sending smtp server is not this domain. In such case, add Sender field with an email of the protected domain.
47
-	// Return-Path: Email where to send bounds.
48
-	var $reply_to;		// Reply-To:	Email where to send replies from mailer software (mailer use From if reply-to not defined, Gmail use gmail account if reply-to not defined)
49
-	var $errors_to;		// Errors-To:	Email where to send errors.
50
-	var $addr_to;
51
-	var $addr_cc;
52
-	var $addr_bcc;
53
-	var $trackid;
54
-
55
-	var $mixed_boundary;
56
-	var $related_boundary;
57
-	var $alternative_boundary;
58
-	var $deliveryreceipt;
59
-
60
-	var $eol;
61
-	var $eol2;
62
-
63
-	/**
64
-	 * @var string Error code (or message)
65
-	 */
66
-	public $error='';
67
-
68
-	var $smtps;			// Contains SMTPs object (if this method is used)
69
-	var $phpmailer;		// Contains PHPMailer object (if this method is used)
70
-
71
-	/**
72
-	 * @var string CSS
73
-	 */
74
-	public $css;
75
-	//! Defined css style for body background
76
-	var $styleCSS;
77
-	//! Defined background directly in body tag
78
-	var $bodyCSS;
79
-
80
-	var $headers;
81
-	var $message;
82
-
83
-	// Image
84
-	var $html;
85
-	var $image_boundary;
86
-	var $atleastoneimage=0;    // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used).
87
-	var $html_images=array();
88
-	var $images_encoded=array();
89
-	var $image_types = array(
39
+    public $sendcontext;
40
+    public $sendmode;
41
+    public $sendsetup;
42
+
43
+    var $subject;      	// Topic:       Subject of email
44
+    var $addr_from;    	// From:		Label and EMail of sender (must include '<>'). For example '<[email protected]>' or 'John Doe <[email protected]>' or '<[email protected]>'). Note that with gmail smtps, value here is forced by google to account (but not the reply-to).
45
+    // Sender:      Who send the email ("Sender" has sent emails on behalf of "From").
46
+    //              Use it when the "From" is an email of a domain that is a SPF protected domain, and sending smtp server is not this domain. In such case, add Sender field with an email of the protected domain.
47
+    // Return-Path: Email where to send bounds.
48
+    var $reply_to;		// Reply-To:	Email where to send replies from mailer software (mailer use From if reply-to not defined, Gmail use gmail account if reply-to not defined)
49
+    var $errors_to;		// Errors-To:	Email where to send errors.
50
+    var $addr_to;
51
+    var $addr_cc;
52
+    var $addr_bcc;
53
+    var $trackid;
54
+
55
+    var $mixed_boundary;
56
+    var $related_boundary;
57
+    var $alternative_boundary;
58
+    var $deliveryreceipt;
59
+
60
+    var $eol;
61
+    var $eol2;
62
+
63
+    /**
64
+     * @var string Error code (or message)
65
+     */
66
+    public $error='';
67
+
68
+    var $smtps;			// Contains SMTPs object (if this method is used)
69
+    var $phpmailer;		// Contains PHPMailer object (if this method is used)
70
+
71
+    /**
72
+     * @var string CSS
73
+     */
74
+    public $css;
75
+    //! Defined css style for body background
76
+    var $styleCSS;
77
+    //! Defined background directly in body tag
78
+    var $bodyCSS;
79
+
80
+    var $headers;
81
+    var $message;
82
+
83
+    // Image
84
+    var $html;
85
+    var $image_boundary;
86
+    var $atleastoneimage=0;    // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used).
87
+    var $html_images=array();
88
+    var $images_encoded=array();
89
+    var $image_types = array(
90 90
         'gif'  => 'image/gif',
91
-		'jpg'  => 'image/jpeg',
92
-		'jpeg' => 'image/jpeg',
93
-		'jpe'  => 'image/jpeg',
94
-		'bmp'  => 'image/bmp',
95
-		'png'  => 'image/png',
96
-		'tif'  => 'image/tiff',
91
+        'jpg'  => 'image/jpeg',
92
+        'jpeg' => 'image/jpeg',
93
+        'jpe'  => 'image/jpeg',
94
+        'bmp'  => 'image/bmp',
95
+        'png'  => 'image/png',
96
+        'tif'  => 'image/tiff',
97 97
         'tiff' => 'image/tiff',
98 98
     );
99 99
 
100 100
 
101
-	/**
102
-	 *	CMailFile
103
-	 *
104
-	 *	@param 	string	$subject             Topic/Subject of mail
105
-	 *	@param 	string	$to                  Recipients emails (RFC 2822: "Name firstname <email>[, ...]" or "email[, ...]" or "<email>[, ...]"). Note: the keyword '__SUPERVISOREMAIL__' is not allowed here and must be replaced by caller.
106
-	 *	@param 	string	$from                Sender email      (RFC 2822: "Name firstname <email>[, ...]" or "email[, ...]" or "<email>[, ...]")
107
-	 *	@param 	string	$msg                 Message
108
-	 *	@param 	array	$filename_list       List of files to attach (full path of filename on file system)
109
-	 *	@param 	array	$mimetype_list       List of MIME type of attached files
110
-	 *	@param 	array	$mimefilename_list   List of attached file name in message
111
-	 *	@param 	string	$addr_cc             Email cc
112
-	 *	@param 	string	$addr_bcc            Email bcc (Note: This is autocompleted with MAIN_MAIL_AUTOCOPY_TO if defined)
113
-	 *	@param 	int		$deliveryreceipt     Ask a delivery receipt
114
-	 *	@param 	int		$msgishtml           1=String IS already html, 0=String IS NOT html, -1=Unknown make autodetection (with fast mode, not reliable)
115
-	 *	@param 	string	$errors_to      	 Email for errors-to
116
-	 *	@param	string	$css                 Css option
117
-	 *	@param	string	$trackid             Tracking string (contains type and id of related element)
118
-	 *  @param  string  $moreinheader        More in header. $moreinheader must contains the "\r\n" (TODO not supported for other MAIL_SEND_MODE different than 'phpmail' and 'smtps' for the moment)
119
-	 *  @param  string  $sendcontext      	 'standard', 'emailing', ... (used to define with sending mode and parameters to use)
120
-	 *  @param	string	$replyto			 Reply-to email (will be set to same value than From by default if not provided)
121
-	 */
122
-	function __construct($subject, $to, $from, $msg, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=0, $errors_to='', $css='', $trackid='', $moreinheader='', $sendcontext='standard', $replyto='')
123
-	{
124
-		global $conf, $dolibarr_main_data_root;
125
-
126
-		$this->sendcontext = $sendcontext;
127
-
128
-		if (empty($replyto)) $replyto=$from;
129
-
130
-		// Define this->sendmode
131
-		$this->sendmode = '';
132
-		if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
133
-		{
134
-			$this->sendmode = $conf->global->MAIN_MAIL_SENDMODE_EMAILING;
135
-		}
136
-		if (empty($this->sendmode)) $this->sendmode=$conf->global->MAIN_MAIL_SENDMODE;
137
-		if (empty($this->sendmode)) $this->sendmode='mail';
138
-
139
-		// We define end of line (RFC 821).
140
-		$this->eol="\r\n";
141
-		// We define end of line for header fields (RFC 822bis section 2.3 says header must contains \r\n).
142
-		$this->eol2="\r\n";
143
-		if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
144
-		{
145
-			$this->eol="\n";
146
-			$this->eol2="\n";
147
-			$moreinheader = str_replace("\r\n","\n",$moreinheader);
148
-		}
149
-
150
-		// On defini mixed_boundary
151
-		$this->mixed_boundary = "multipart_x." . time() . ".x_boundary";
152
-
153
-		// On defini related_boundary
154
-		$this->related_boundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);	// Force md5 hash (does not contains special chars)
155
-
156
-		// On defini alternative_boundary
157
-		$this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);	// Force md5 hash (does not contains special chars)
158
-
159
-		dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, trackid=$trackid sendcontext=$sendcontext", LOG_DEBUG);
160
-		dol_syslog("CMailFile::CMailfile: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG);
161
-
162
-		if (empty($subject))
163
-		{
164
-			dol_syslog("CMailFile::CMailfile: Try to send an email with empty subject");
165
-			$this->error='ErrorSubjectIsRequired';
166
-			return;
167
-		}
168
-		if (empty($msg))
169
-		{
170
-		    dol_syslog("CMailFile::CMailfile: Try to send an email with empty body");
171
-		    $msg='.';     // Avoid empty message (with empty message conten show a multipart structure)
172
-		}
173
-
174
-		// Detect if message is HTML (use fast method)
175
-		if ($msgishtml == -1)
176
-		{
177
-			$this->msgishtml = 0;
178
-			if (dol_textishtml($msg)) $this->msgishtml = 1;
179
-		}
180
-		else
181
-		{
182
-			$this->msgishtml = $msgishtml;
183
-		}
184
-
185
-		global $dolibarr_main_url_root;
186
-
187
-		// Define $urlwithroot
188
-		$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
189
-		$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
190
-		//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
191
-
192
-		// Replace relative /viewimage to absolute path
193
-		$msg = preg_replace('/src="'.preg_quote(DOL_URL_ROOT,'/').'\/viewimage\.php/ims', 'src="'.$urlwithroot.'/viewimage.php', $msg, -1, $nbrep);
194
-
195
-		if (! empty($conf->global->MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML)) $this->msgishtml=1; // To force to send everything with content type html.
196
-
197
-		// Detect images
198
-		if ($this->msgishtml)
199
-		{
200
-			$this->html = $msg;
201
-
202
-			if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS))
203
-			{
204
-				$findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias');
205
-			}
206
-
207
-			// Define if there is at least one file
208
-			if ($findimg)
209
-			{
210
-				foreach ($this->html_images as $i => $val)
211
-				{
212
-					if ($this->html_images[$i])
213
-					{
214
-						$this->atleastoneimage=1;
215
-						dol_syslog("CMailFile::CMailfile: html_images[$i]['name']=".$this->html_images[$i]['name'], LOG_DEBUG);
216
-					}
217
-				}
218
-			}
219
-		}
220
-
221
-		// Define if there is at least one file
222
-		if (is_array($filename_list))
223
-		{
224
-			foreach ($filename_list as $i => $val)
225
-			{
226
-				if ($filename_list[$i])
227
-				{
228
-					$this->atleastonefile=1;
229
-					dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i], LOG_DEBUG);
230
-				}
231
-			}
232
-		}
233
-
234
-		// Add autocopy to (Note: Adding bcc for specific modules are also done from pages)
235
-		if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO;
236
-
237
-		// Action according to choosed sending method
238
-		if ($this->sendmode == 'mail')
239
-		{
240
-			// Use mail php function (default PHP method)
241
-			// ------------------------------------------
242
-
243
-			$smtp_headers = "";
244
-			$mime_headers = "";
245
-			$text_body = "";
246
-			$files_encoded = "";
247
-
248
-			// Define smtp_headers
249
-			$this->subject = $subject;
250
-			$this->addr_from = $from;
251
-			$this->reply_to = $replyto;
252
-			$this->errors_to = $errors_to;
253
-			$this->addr_to = $to;
254
-			$this->addr_cc = $addr_cc;
255
-			$this->addr_bcc = $addr_bcc;
256
-			$this->deliveryreceipt = $deliveryreceipt;
257
-			$this->trackid = $trackid;
258
-
259
-			$smtp_headers = $this->write_smtpheaders();
260
-			if (! empty($moreinheader)) $smtp_headers.=$moreinheader;   // $moreinheader contains the \r\n
261
-
262
-			// Define mime_headers
263
-			$mime_headers = $this->write_mimeheaders($filename_list, $mimefilename_list);
264
-
265
-			if (! empty($this->html))
266
-			{
267
-				if (!empty($css))
268
-				{
269
-					$this->css = $css;
270
-					$this->buildCSS();    // Build a css style (mode = all) into this->styleCSS and this->bodyCSS
271
-				}
272
-
273
-				$msg = $this->html;
274
-			}
275
-
276
-			// Define body in text_body
277
-			$text_body = $this->write_body($msg);
278
-
279
-			// Add attachments to text_encoded
280
-			if ($this->atleastonefile)
281
-			{
282
-				$files_encoded = $this->write_files($filename_list,$mimetype_list,$mimefilename_list);
283
-			}
284
-
285
-			// We now define $this->headers and $this->message
286
-			$this->headers = $smtp_headers . $mime_headers;
287
-			// On nettoie le header pour qu'il ne se termine pas par un retour chariot.
288
-			// Ceci evite aussi les lignes vides en fin qui peuvent etre interpretees
289
-			// comme des injections mail par les serveurs de messagerie.
290
-			$this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers);
291
-
292
-			//$this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol;
293
-			$this->message = 'This is a message with multiple parts in MIME format.'.$this->eol;
294
-			$this->message.= $text_body . $files_encoded;
295
-			$this->message.= "--" . $this->mixed_boundary . "--" . $this->eol;
296
-		}
297
-		else if ($this->sendmode == 'smtps')
298
-		{
299
-			// Use SMTPS library
300
-			// ------------------------------------------
301
-
302
-			require_once DOL_DOCUMENT_ROOT.'/core/class/smtps.class.php';
303
-			$smtps = new SMTPs();
304
-			$smtps->setCharSet($conf->file->character_set_client);
305
-
306
-			$smtps->setSubject($this->encodetorfc2822($subject));
307
-			$smtps->setTO($this->getValidAddress($to,0,1));
308
-			$smtps->setFrom($this->getValidAddress($from,0,1));
309
-			$smtps->setTrackId($trackid);
310
-			$smtps->setReplyTo($this->getValidAddress($replyto,0,1));
311
-
312
-			if (! empty($moreinheader)) $smtps->setMoreInHeader($moreinheader);
313
-
314
-			if (! empty($this->html))
315
-			{
316
-				if (!empty($css))
317
-				{
318
-					$this->css = $css;
319
-					$this->buildCSS();
320
-				}
321
-				$msg = $this->html;
322
-				$msg = $this->checkIfHTML($msg);
323
-			}
324
-
325
-			if ($this->msgishtml) $smtps->setBodyContent($msg,'html');
326
-			else $smtps->setBodyContent($msg,'plain');
327
-
328
-			if ($this->atleastoneimage)
329
-			{
330
-				foreach ($this->images_encoded as $img)
331
-				{
332
-					$smtps->setImageInline($img['image_encoded'],$img['name'],$img['content_type'],$img['cid']);
333
-				}
334
-			}
335
-
336
-			if ($this->atleastonefile)
337
-			{
338
-				foreach ($filename_list as $i => $val)
339
-				{
340
-					$content=file_get_contents($filename_list[$i]);
341
-					$smtps->setAttachment($content,$mimefilename_list[$i],$mimetype_list[$i]);
342
-				}
343
-			}
344
-
345
-			$smtps->setCC($addr_cc);
346
-			$smtps->setBCC($addr_bcc);
347
-			$smtps->setErrorsTo($errors_to);
348
-			$smtps->setDeliveryReceipt($deliveryreceipt);
349
-
350
-			$this->smtps=$smtps;
351
-		}
352
-		else if ($this->sendmode == 'swiftmailer')
353
-		{
354
-			// Use Swift Mailer library
355
-			// ------------------------------------------
101
+    /**
102
+     *	CMailFile
103
+     *
104
+     *	@param 	string	$subject             Topic/Subject of mail
105
+     *	@param 	string	$to                  Recipients emails (RFC 2822: "Name firstname <email>[, ...]" or "email[, ...]" or "<email>[, ...]"). Note: the keyword '__SUPERVISOREMAIL__' is not allowed here and must be replaced by caller.
106
+     *	@param 	string	$from                Sender email      (RFC 2822: "Name firstname <email>[, ...]" or "email[, ...]" or "<email>[, ...]")
107
+     *	@param 	string	$msg                 Message
108
+     *	@param 	array	$filename_list       List of files to attach (full path of filename on file system)
109
+     *	@param 	array	$mimetype_list       List of MIME type of attached files
110
+     *	@param 	array	$mimefilename_list   List of attached file name in message
111
+     *	@param 	string	$addr_cc             Email cc
112
+     *	@param 	string	$addr_bcc            Email bcc (Note: This is autocompleted with MAIN_MAIL_AUTOCOPY_TO if defined)
113
+     *	@param 	int		$deliveryreceipt     Ask a delivery receipt
114
+     *	@param 	int		$msgishtml           1=String IS already html, 0=String IS NOT html, -1=Unknown make autodetection (with fast mode, not reliable)
115
+     *	@param 	string	$errors_to      	 Email for errors-to
116
+     *	@param	string	$css                 Css option
117
+     *	@param	string	$trackid             Tracking string (contains type and id of related element)
118
+     *  @param  string  $moreinheader        More in header. $moreinheader must contains the "\r\n" (TODO not supported for other MAIL_SEND_MODE different than 'phpmail' and 'smtps' for the moment)
119
+     *  @param  string  $sendcontext      	 'standard', 'emailing', ... (used to define with sending mode and parameters to use)
120
+     *  @param	string	$replyto			 Reply-to email (will be set to same value than From by default if not provided)
121
+     */
122
+    function __construct($subject, $to, $from, $msg, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=0, $errors_to='', $css='', $trackid='', $moreinheader='', $sendcontext='standard', $replyto='')
123
+    {
124
+        global $conf, $dolibarr_main_data_root;
125
+
126
+        $this->sendcontext = $sendcontext;
127
+
128
+        if (empty($replyto)) $replyto=$from;
129
+
130
+        // Define this->sendmode
131
+        $this->sendmode = '';
132
+        if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
133
+        {
134
+            $this->sendmode = $conf->global->MAIN_MAIL_SENDMODE_EMAILING;
135
+        }
136
+        if (empty($this->sendmode)) $this->sendmode=$conf->global->MAIN_MAIL_SENDMODE;
137
+        if (empty($this->sendmode)) $this->sendmode='mail';
138
+
139
+        // We define end of line (RFC 821).
140
+        $this->eol="\r\n";
141
+        // We define end of line for header fields (RFC 822bis section 2.3 says header must contains \r\n).
142
+        $this->eol2="\r\n";
143
+        if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
144
+        {
145
+            $this->eol="\n";
146
+            $this->eol2="\n";
147
+            $moreinheader = str_replace("\r\n","\n",$moreinheader);
148
+        }
149
+
150
+        // On defini mixed_boundary
151
+        $this->mixed_boundary = "multipart_x." . time() . ".x_boundary";
152
+
153
+        // On defini related_boundary
154
+        $this->related_boundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);	// Force md5 hash (does not contains special chars)
155
+
156
+        // On defini alternative_boundary
157
+        $this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);	// Force md5 hash (does not contains special chars)
158
+
159
+        dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, trackid=$trackid sendcontext=$sendcontext", LOG_DEBUG);
160
+        dol_syslog("CMailFile::CMailfile: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG);
161
+
162
+        if (empty($subject))
163
+        {
164
+            dol_syslog("CMailFile::CMailfile: Try to send an email with empty subject");
165
+            $this->error='ErrorSubjectIsRequired';
166
+            return;
167
+        }
168
+        if (empty($msg))
169
+        {
170
+            dol_syslog("CMailFile::CMailfile: Try to send an email with empty body");
171
+            $msg='.';     // Avoid empty message (with empty message conten show a multipart structure)
172
+        }
173
+
174
+        // Detect if message is HTML (use fast method)
175
+        if ($msgishtml == -1)
176
+        {
177
+            $this->msgishtml = 0;
178
+            if (dol_textishtml($msg)) $this->msgishtml = 1;
179
+        }
180
+        else
181
+        {
182
+            $this->msgishtml = $msgishtml;
183
+        }
184
+
185
+        global $dolibarr_main_url_root;
186
+
187
+        // Define $urlwithroot
188
+        $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
189
+        $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
190
+        //$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
191
+
192
+        // Replace relative /viewimage to absolute path
193
+        $msg = preg_replace('/src="'.preg_quote(DOL_URL_ROOT,'/').'\/viewimage\.php/ims', 'src="'.$urlwithroot.'/viewimage.php', $msg, -1, $nbrep);
194
+
195
+        if (! empty($conf->global->MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML)) $this->msgishtml=1; // To force to send everything with content type html.
196
+
197
+        // Detect images
198
+        if ($this->msgishtml)
199
+        {
200
+            $this->html = $msg;
201
+
202
+            if (! empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS))
203
+            {
204
+                $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias');
205
+            }
206
+
207
+            // Define if there is at least one file
208
+            if ($findimg)
209
+            {
210
+                foreach ($this->html_images as $i => $val)
211
+                {
212
+                    if ($this->html_images[$i])
213
+                    {
214
+                        $this->atleastoneimage=1;
215
+                        dol_syslog("CMailFile::CMailfile: html_images[$i]['name']=".$this->html_images[$i]['name'], LOG_DEBUG);
216
+                    }
217
+                }
218
+            }
219
+        }
220
+
221
+        // Define if there is at least one file
222
+        if (is_array($filename_list))
223
+        {
224
+            foreach ($filename_list as $i => $val)
225
+            {
226
+                if ($filename_list[$i])
227
+                {
228
+                    $this->atleastonefile=1;
229
+                    dol_syslog("CMailFile::CMailfile: filename_list[$i]=".$filename_list[$i].", mimetype_list[$i]=".$mimetype_list[$i]." mimefilename_list[$i]=".$mimefilename_list[$i], LOG_DEBUG);
230
+                }
231
+            }
232
+        }
233
+
234
+        // Add autocopy to (Note: Adding bcc for specific modules are also done from pages)
235
+        if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO;
236
+
237
+        // Action according to choosed sending method
238
+        if ($this->sendmode == 'mail')
239
+        {
240
+            // Use mail php function (default PHP method)
241
+            // ------------------------------------------
242
+
243
+            $smtp_headers = "";
244
+            $mime_headers = "";
245
+            $text_body = "";
246
+            $files_encoded = "";
247
+
248
+            // Define smtp_headers
249
+            $this->subject = $subject;
250
+            $this->addr_from = $from;
251
+            $this->reply_to = $replyto;
252
+            $this->errors_to = $errors_to;
253
+            $this->addr_to = $to;
254
+            $this->addr_cc = $addr_cc;
255
+            $this->addr_bcc = $addr_bcc;
256
+            $this->deliveryreceipt = $deliveryreceipt;
257
+            $this->trackid = $trackid;
258
+
259
+            $smtp_headers = $this->write_smtpheaders();
260
+            if (! empty($moreinheader)) $smtp_headers.=$moreinheader;   // $moreinheader contains the \r\n
261
+
262
+            // Define mime_headers
263
+            $mime_headers = $this->write_mimeheaders($filename_list, $mimefilename_list);
264
+
265
+            if (! empty($this->html))
266
+            {
267
+                if (!empty($css))
268
+                {
269
+                    $this->css = $css;
270
+                    $this->buildCSS();    // Build a css style (mode = all) into this->styleCSS and this->bodyCSS
271
+                }
272
+
273
+                $msg = $this->html;
274
+            }
275
+
276
+            // Define body in text_body
277
+            $text_body = $this->write_body($msg);
278
+
279
+            // Add attachments to text_encoded
280
+            if ($this->atleastonefile)
281
+            {
282
+                $files_encoded = $this->write_files($filename_list,$mimetype_list,$mimefilename_list);
283
+            }
284
+
285
+            // We now define $this->headers and $this->message
286
+            $this->headers = $smtp_headers . $mime_headers;
287
+            // On nettoie le header pour qu'il ne se termine pas par un retour chariot.
288
+            // Ceci evite aussi les lignes vides en fin qui peuvent etre interpretees
289
+            // comme des injections mail par les serveurs de messagerie.
290
+            $this->headers = preg_replace("/([\r\n]+)$/i","",$this->headers);
291
+
292
+            //$this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol;
293
+            $this->message = 'This is a message with multiple parts in MIME format.'.$this->eol;
294
+            $this->message.= $text_body . $files_encoded;
295
+            $this->message.= "--" . $this->mixed_boundary . "--" . $this->eol;
296
+        }
297
+        else if ($this->sendmode == 'smtps')
298
+        {
299
+            // Use SMTPS library
300
+            // ------------------------------------------
301
+
302
+            require_once DOL_DOCUMENT_ROOT.'/core/class/smtps.class.php';
303
+            $smtps = new SMTPs();
304
+            $smtps->setCharSet($conf->file->character_set_client);
305
+
306
+            $smtps->setSubject($this->encodetorfc2822($subject));
307
+            $smtps->setTO($this->getValidAddress($to,0,1));
308
+            $smtps->setFrom($this->getValidAddress($from,0,1));
309
+            $smtps->setTrackId($trackid);
310
+            $smtps->setReplyTo($this->getValidAddress($replyto,0,1));
311
+
312
+            if (! empty($moreinheader)) $smtps->setMoreInHeader($moreinheader);
313
+
314
+            if (! empty($this->html))
315
+            {
316
+                if (!empty($css))
317
+                {
318
+                    $this->css = $css;
319
+                    $this->buildCSS();
320
+                }
321
+                $msg = $this->html;
322
+                $msg = $this->checkIfHTML($msg);
323
+            }
324
+
325
+            if ($this->msgishtml) $smtps->setBodyContent($msg,'html');
326
+            else $smtps->setBodyContent($msg,'plain');
327
+
328
+            if ($this->atleastoneimage)
329
+            {
330
+                foreach ($this->images_encoded as $img)
331
+                {
332
+                    $smtps->setImageInline($img['image_encoded'],$img['name'],$img['content_type'],$img['cid']);
333
+                }
334
+            }
335
+
336
+            if ($this->atleastonefile)
337
+            {
338
+                foreach ($filename_list as $i => $val)
339
+                {
340
+                    $content=file_get_contents($filename_list[$i]);
341
+                    $smtps->setAttachment($content,$mimefilename_list[$i],$mimetype_list[$i]);
342
+                }
343
+            }
344
+
345
+            $smtps->setCC($addr_cc);
346
+            $smtps->setBCC($addr_bcc);
347
+            $smtps->setErrorsTo($errors_to);
348
+            $smtps->setDeliveryReceipt($deliveryreceipt);
349
+
350
+            $this->smtps=$smtps;
351
+        }
352
+        else if ($this->sendmode == 'swiftmailer')
353
+        {
354
+            // Use Swift Mailer library
355
+            // ------------------------------------------
356 356
 
357 357
             $host = dol_getprefix('email');
358 358
 
@@ -361,419 +361,419 @@  discard block
 block discarded – undo
361 361
             require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Exception/InvalidEmail.php';
362 362
             require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Exception/NoDomainPart.php';
363 363
             require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/EmailParser.php';
364
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/EmailLexer.php';
365
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/EmailValidator.php';
366
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Warning/Warning.php';
367
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Warning/LocalTooLong.php';
368
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Parser/Parser.php';
369
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Parser/DomainPart.php';
370
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Parser/LocalPart.php';
371
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Validation/EmailValidation.php';
372
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Validation/RFCValidation.php';
364
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/EmailLexer.php';
365
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/EmailValidator.php';
366
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Warning/Warning.php';
367
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Warning/LocalTooLong.php';
368
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Parser/Parser.php';
369
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Parser/DomainPart.php';
370
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Parser/LocalPart.php';
371
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Validation/EmailValidation.php';
372
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/egulias/email-validator/EmailValidator/Validation/RFCValidation.php';
373 373
 
374 374
             require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/InputByteStream.php';
375
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/Signer.php';
376
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php';
377
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php';
378
-			//require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/SignedMessage.php';
379
-			require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php';
380
-			// Create the message
381
-			//$this->message = Swift_Message::newInstance();
382
-			$this->message = new Swift_Message();
375
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/Signer.php';
376
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php';
377
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php';
378
+            //require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/classes/Swift/SignedMessage.php';
379
+            require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php';
380
+            // Create the message
381
+            //$this->message = Swift_Message::newInstance();
382
+            $this->message = new Swift_Message();
383 383
             //$this->message = new Swift_SignedMessage();
384 384
             // Adding a trackid header to a message
385
-			$headers = $this->message->getHeaders();
386
-			$headers->addTextHeader('X-Dolibarr-TRACKID', $trackid . '@' . $host);
387
-			$headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host;
388
-			$msgid = $headers->get('Message-ID');
389
-			$msgid->setId($headerID);
390
-			$headers->addIdHeader('References', $headerID);
391
-			// TODO if (! empty($moreinheader)) ...
392
-
393
-			// Give the message a subject
394
-			try {
395
-				$result = $this->message->setSubject($subject);
396
-			} catch (Exception $e) {
397
-				$this->errors[] =  $e->getMessage();
398
-			}
399
-
400
-			// Set the From address with an associative array
401
-			//$this->message->setFrom(array('[email protected]' => 'John Doe'));
402
-			if (! empty($from)) {
385
+            $headers = $this->message->getHeaders();
386
+            $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid . '@' . $host);
387
+            $headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host;
388
+            $msgid = $headers->get('Message-ID');
389
+            $msgid->setId($headerID);
390
+            $headers->addIdHeader('References', $headerID);
391
+            // TODO if (! empty($moreinheader)) ...
392
+
393
+            // Give the message a subject
394
+            try {
395
+                $result = $this->message->setSubject($subject);
396
+            } catch (Exception $e) {
397
+                $this->errors[] =  $e->getMessage();
398
+            }
399
+
400
+            // Set the From address with an associative array
401
+            //$this->message->setFrom(array('[email protected]' => 'John Doe'));
402
+            if (! empty($from)) {
403 403
                 try {
404
-                	$result = $this->message->setFrom($this->getArrayAddress($from));
404
+                    $result = $this->message->setFrom($this->getArrayAddress($from));
405 405
                 } catch (Exception $e) {
406 406
                     $this->errors[] = $e->getMessage();
407 407
                 }
408 408
             }
409 409
 
410
-			// Set the To addresses with an associative array
411
-			if (! empty($to)) {
410
+            // Set the To addresses with an associative array
411
+            if (! empty($to)) {
412 412
                 try {
413
-                	$result = $this->message->setTo($this->getArrayAddress($to));
413
+                    $result = $this->message->setTo($this->getArrayAddress($to));
414 414
                 } catch (Exception $e) {
415 415
                     $this->errors[] = $e->getMessage();
416 416
                 }
417 417
             }
418 418
 
419
-			if (! empty($replyto)) {
419
+            if (! empty($replyto)) {
420 420
                 try {
421
-                	$result = $this->message->SetReplyTo($this->getArrayAddress($replyto));
421
+                    $result = $this->message->SetReplyTo($this->getArrayAddress($replyto));
422 422
                 } catch (Exception $e) {
423 423
                     $this->errors[] = $e->getMessage();
424 424
                 }
425 425
             }
426 426
 
427
-			try {
428
-				$result = $this->message->setCharSet($conf->file->character_set_client);
429
-			} catch (Exception $e) {
430
-				$this->errors[] =  $e->getMessage();
431
-			}
432
-
433
-			if (! empty($this->html))
434
-			{
435
-				if (!empty($css))
436
-				{
437
-					$this->css = $css;
438
-					$this->buildCSS();
439
-				}
440
-				$msg = $this->html;
441
-				$msg = $this->checkIfHTML($msg);
442
-			}
443
-
444
-			if ($this->atleastoneimage)
445
-			{
446
-				foreach ($this->images_encoded as $img)
447
-				{
448
-					//$img['fullpath'],$img['image_encoded'],$img['name'],$img['content_type'],$img['cid']
449
-					$attachment = Swift_Image::fromPath($img['fullpath'], $img['content_type']);
450
-					// embed image
451
-					$imgcid = $this->message->embed($attachment);
452
-					// replace cid by the one created by swiftmail in html message
453
-					$msg = str_replace("cid:".$img['cid'], $imgcid, $msg);
454
-				}
455
-			}
456
-
457
-			if ($this->msgishtml) {
458
-				$this->message->setBody($msg,'text/html');
459
-				// And optionally an alternative body
460
-				$this->message->addPart(html_entity_decode(strip_tags($msg)), 'text/plain');
461
-			} else {
462
-				$this->message->setBody($msg,'text/plain');
463
-				// And optionally an alternative body
464
-				$this->message->addPart($msg, 'text/html');
465
-			}
466
-
467
-			if ($this->atleastonefile)
468
-			{
469
-				foreach ($filename_list as $i => $val)
470
-				{
471
-					//$this->message->attach(Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]));
472
-					$attachment = Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]);
473
-					$this->message->attach($attachment);
474
-				}
475
-			}
476
-
477
-			if (! empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc));
478
-			if (! empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc));
479
-			//if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to);
480
-			if (isset($deliveryreceipt) && $deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from));
481
-		}
482
-		else
483
-		{
484
-			// Send mail method not correctly defined
485
-			// --------------------------------------
486
-			$this->error = 'Bad value for sendmode';
487
-		}
488
-	}
489
-
490
-
491
-	/**
492
-	 * Send mail that was prepared by constructor.
493
-	 *
494
-	 * @return    boolean     True if mail sent, false otherwise
495
-	 */
496
-	function sendfile()
497
-	{
498
-		global $conf,$db,$langs;
499
-
500
-		$errorlevel=error_reporting();
501
-		//error_reporting($errorlevel ^ E_WARNING);   // Desactive warnings
502
-
503
-		$res=false;
504
-
505
-		if (empty($conf->global->MAIN_DISABLE_ALL_MAILS) || !empty($conf->global->MAIN_MAIL_FORCE_SENDTO))
506
-		{
507
-			require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
508
-			$hookmanager = new HookManager($db);
509
-			$hookmanager->initHooks(array('mail'));
510
-
511
-			$parameters=array(); $action='';
512
-			$reshook = $hookmanager->executeHooks('sendMail', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
513
-			if ($reshook < 0)
514
-			{
515
-				$this->error = "Error in hook maildao sendMail " . $reshook;
516
-				dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR);
517
-
518
-				return $reshook;
519
-			}
520
-			if ($reshook == 1)	// Hook replace standard code
521
-			{
522
-				return true;
523
-			}
524
-
525
-			// Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL
526
-			if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL=10;
527
-			$tmparray1 = explode(',', $this->addr_to);
528
-			if (count($tmparray1) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)
529
-			{
530
-				$this->error = 'Too much recipients in to:';
531
-				dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
532
-				return false;
533
-			}
534
-			if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL=10;
535
-			$tmparray2 = explode(',', $this->addr_cc);
536
-			if (count($tmparray2) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)
537
-			{
538
-				$this->error = 'Too much recipients in cc:';
539
-				dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
540
-				return false;
541
-			}
542
-			if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL=10;
543
-			$tmparray3 = explode(',', $this->addr_bcc);
544
-			if (count($tmparray3) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)
545
-			{
546
-				$this->error = 'Too much recipients in bcc:';
547
-				dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
548
-				return false;
549
-			}
550
-			if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL=10;
551
-			if ((count($tmparray1)+count($tmparray2)+count($tmparray3)) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
552
-			{
553
-				$this->error = 'Too much recipients in to:, cc:, bcc:';
554
-				dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
555
-				return false;
556
-			}
557
-
558
-			$keyforsmtpserver='MAIN_MAIL_SMTP_SERVER';
559
-			$keyforsmtpport  ='MAIN_MAIL_SMTP_PORT';
560
-			$keyforsmtpid    ='MAIN_MAIL_SMTPS_ID';
561
-			$keyforsmtppw    ='MAIN_MAIL_SMTPS_PW';
562
-			$keyfortls       ='MAIN_MAIL_EMAIL_TLS';
563
-			$keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS';
564
-			if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
565
-			{
566
-				$keyforsmtpserver='MAIN_MAIL_SMTP_SERVER_EMAILING';
567
-				$keyforsmtpport  ='MAIN_MAIL_SMTP_PORT_EMAILING';
568
-				$keyforsmtpid    ='MAIN_MAIL_SMTPS_ID_EMAILING';
569
-				$keyforsmtppw    ='MAIN_MAIL_SMTPS_PW_EMAILING';
570
-				$keyfortls       ='MAIN_MAIL_EMAIL_TLS_EMAILING';
571
-				$keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
572
-			}
573
-
574
-			if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO))
575
-			{
576
-				$this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO;
577
-				$this->addr_cc = '';
578
-				$this->addr_bcc = '';
579
-			}
580
-
581
-			// Action according to choosed sending method
582
-			if ($this->sendmode == 'mail')
583
-			{
584
-				// Use mail php function (default PHP method)
585
-				// ------------------------------------------
586
-				dol_syslog("CMailFile::sendfile addr_to=".$this->addr_to.", subject=".$this->subject, LOG_DEBUG);
587
-				dol_syslog("CMailFile::sendfile header=\n".$this->headers, LOG_DEBUG);
588
-				//dol_syslog("CMailFile::sendfile message=\n".$message);
589
-
590
-				// If Windows, sendmail_from must be defined
591
-				if (isset($_SERVER["WINDIR"]))
592
-				{
593
-					if (empty($this->addr_from)) $this->addr_from = '[email protected]';
594
-					@ini_set('sendmail_from',$this->getValidAddress($this->addr_from,2));
595
-				}
596
-
597
-				// Force parameters
598
-				if (! empty($conf->global->$keyforsmtpserver)) ini_set('SMTP',$conf->global->$keyforsmtpserver);
599
-				if (! empty($conf->global->$keyforsmtpport))   ini_set('smtp_port',$conf->global->$keyforsmtpport);
600
-
601
-				$res=true;
602
-				if ($res && ! $this->subject)
603
-				{
604
-					$this->error="Failed to send mail with php mail to HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port')."<br>Subject is empty";
605
-					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
606
-					$res=false;
607
-				}
608
-				$dest=$this->getValidAddress($this->addr_to,2);
609
-				if ($res && ! $dest)
610
-				{
611
-					$this->error="Failed to send mail with php mail to HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port')."<br>Recipient address '$dest' invalid";
612
-					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
613
-					$res=false;
614
-				}
615
-
616
-				if ($res)
617
-				{
618
-					$additionnalparam = '';	// By default
619
-					if (! empty($conf->global->MAIN_MAIL_ALLOW_SENDMAIL_F))
620
-					{
621
-						// le "Return-Path" (retour des messages bounced) dans les header ne fonctionne pas avec tous les MTA
622
-						// Le forcage de la valeur grace à l'option -f de sendmail est donc possible si la constante MAIN_MAIL_ALLOW_SENDMAIL_F est definie.
623
-						// Having this variable defined may create problems with some sendmail (option -f refused)
624
-						// Having this variable not defined may create problems with some other sendmail (option -f required)
625
-						$additionnalparam .= ($additionnalparam?' ':'').(! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? '-f' . $this->getValidAddress($conf->global->MAIN_MAIL_ERRORS_TO,2) : ($this->addr_from != '' ? '-f' . $this->getValidAddress($this->addr_from,2) : '') );
626
-					}
627
-					if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_BA))    // To force usage of -ba option. This option tells sendmail to read From: or Sender: to setup sender
628
-					{
629
-						$additionnalparam .= ($additionnalparam?' ':'').'-ba';
630
-					}
631
-
632
-					if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_ADDPARAM)) $additionnalparam .= ($additionnalparam?' ':'').'-U '.$additionnalparam; // Use -U to add additionnal params
633
-
634
-					dol_syslog("CMailFile::sendfile: mail start HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port').", additionnal_parameters=".$additionnalparam, LOG_DEBUG);
635
-
636
-					$this->message=stripslashes($this->message);
637
-
638
-					if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
639
-
640
-					if (! empty($additionnalparam)) $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers, $additionnalparam);
641
-					else $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers);
642
-
643
-					if (! $res)
644
-					{
645
-						$langs->load("errors");
646
-						$this->error="Failed to send mail with php mail";
647
-						$linuxlike=1;
648
-						if (preg_match('/^win/i',PHP_OS)) $linuxlike=0;
649
-						if (preg_match('/^mac/i',PHP_OS)) $linuxlike=0;
650
-						if (! $linuxlike)
651
-						{
652
-							$this->error.=" to HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port');	// This values are value used only for non linuxlike systems
653
-						}
654
-						$this->error.=".<br>";
655
-						$this->error.=$langs->trans("ErrorPhpMailDelivery");
656
-						dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
657
-					}
658
-					else
659
-					{
660
-						dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
661
-					}
662
-				}
663
-
664
-				if (isset($_SERVER["WINDIR"]))
665
-				{
666
-					@ini_restore('sendmail_from');
667
-				}
668
-
669
-				// Restore parameters
670
-				if (! empty($conf->global->$keyforsmtpserver))	ini_restore('SMTP');
671
-				if (! empty($conf->global->$keyforsmtpport)) 	ini_restore('smtp_port');
672
-			}
673
-			else if ($this->sendmode == 'smtps')
674
-			{
675
-				if (! is_object($this->smtps))
676
-				{
677
-					$this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Constructor of object CMailFile was not initialized without errors.";
678
-					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
679
-					return false;
680
-				}
681
-
682
-				// Use SMTPS library
683
-				// ------------------------------------------
684
-				$this->smtps->setTransportType(0);	// Only this method is coded in SMTPs library
685
-
686
-				// Clean parameters
687
-				if (empty($conf->global->$keyforsmtpserver)) $conf->global->$keyforsmtpserver=ini_get('SMTP');
688
-				if (empty($conf->global->$keyforsmtpport))   $conf->global->$keyforsmtpport=ini_get('smtp_port');
689
-
690
-				// If we use SSL/TLS
691
-				$server=$conf->global->$keyforsmtpserver;
692
-				$secure='';
693
-				if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $secure='ssl';
694
-				if (! empty($conf->global->$keyforstarttls) && function_exists('openssl_open')) $secure='tls';
695
-				$server=($secure?$secure.'://':'').$server;
696
-
697
-				$port=$conf->global->$keyforsmtpport;
698
-
699
-				$this->smtps->setHost($server);
700
-				$this->smtps->setPort($port); // 25, 465...;
701
-
702
-				$loginid=''; $loginpass='';
703
-				if (! empty($conf->global->$keyforsmtpid))
704
-				{
705
-					$loginid = $conf->global->$keyforsmtpid;
706
-					$this->smtps->setID($loginid);
707
-				}
708
-				if (! empty($conf->global->$keyforsmtppw))
709
-				{
710
-					$loginpass = $conf->global->$keyforsmtppw;
711
-					$this->smtps->setPW($loginpass);
712
-				}
713
-
714
-				$res=true;
715
-				$from=$this->smtps->getFrom('org');
716
-				if ($res && ! $from)
717
-				{
718
-					$this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Sender address '$from' invalid";
719
-					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
720
-					$res=false;
721
-				}
722
-				$dest=$this->smtps->getTo();
723
-				if ($res && ! $dest)
724
-				{
725
-					$this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Recipient address '$dest' invalid";
726
-					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
727
-					$res=false;
728
-				}
729
-
730
-				if ($res)
731
-				{
732
-					if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->smtps->setDebug(true);
733
-
734
-					$result=$this->smtps->sendMsg();
735
-					//print $result;
736
-
737
-					if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
738
-
739
-					$result=$this->smtps->getErrors();
740
-					if (empty($this->error) && empty($result))
741
-					{
742
-						dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
743
-						$res=true;
744
-					}
745
-					else
746
-					{
747
-						if (empty($this->error)) $this->error=$result;
748
-						dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
749
-						$res=false;
750
-					}
751
-				}
752
-			}
753
-			else if ($this->sendmode == 'swiftmailer')
754
-			{
755
-				// Use Swift Mailer library
756
-				// ------------------------------------------
757
-				require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php';
758
-
759
-				// Clean parameters
760
-				if (empty($conf->global->$keyforsmtpserver)) $conf->global->$keyforsmtpserver=ini_get('SMTP');
761
-				if (empty($conf->global->$keyforsmtpport))   $conf->global->$keyforsmtpport=ini_get('smtp_port');
762
-
763
-				// If we use SSL/TLS
764
-				$server = $conf->global->$keyforsmtpserver;
765
-				$secure = '';
766
-				if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $secure='ssl';
767
-				if (! empty($conf->global->$keyforstarttls) && function_exists('openssl_open')) $secure='tls';
768
-
769
-				$this->transport = new Swift_SmtpTransport($server, $conf->global->$keyforsmtpport, $secure);
770
-
771
-				if (! empty($conf->global->$keyforsmtpid)) $this->transport->setUsername($conf->global->$keyforsmtpid);
772
-				if (! empty($conf->global->$keyforsmtppw)) $this->transport->setPassword($conf->global->$keyforsmtppw);
773
-				//$smtps->_msgReplyTo  = '[email protected]';
774
-
775
-				// Create the Mailer using your created Transport
776
-				$this->mailer = new Swift_Mailer($this->transport);
427
+            try {
428
+                $result = $this->message->setCharSet($conf->file->character_set_client);
429
+            } catch (Exception $e) {
430
+                $this->errors[] =  $e->getMessage();
431
+            }
432
+
433
+            if (! empty($this->html))
434
+            {
435
+                if (!empty($css))
436
+                {
437
+                    $this->css = $css;
438
+                    $this->buildCSS();
439
+                }
440
+                $msg = $this->html;
441
+                $msg = $this->checkIfHTML($msg);
442
+            }
443
+
444
+            if ($this->atleastoneimage)
445
+            {
446
+                foreach ($this->images_encoded as $img)
447
+                {
448
+                    //$img['fullpath'],$img['image_encoded'],$img['name'],$img['content_type'],$img['cid']
449
+                    $attachment = Swift_Image::fromPath($img['fullpath'], $img['content_type']);
450
+                    // embed image
451
+                    $imgcid = $this->message->embed($attachment);
452
+                    // replace cid by the one created by swiftmail in html message
453
+                    $msg = str_replace("cid:".$img['cid'], $imgcid, $msg);
454
+                }
455
+            }
456
+
457
+            if ($this->msgishtml) {
458
+                $this->message->setBody($msg,'text/html');
459
+                // And optionally an alternative body
460
+                $this->message->addPart(html_entity_decode(strip_tags($msg)), 'text/plain');
461
+            } else {
462
+                $this->message->setBody($msg,'text/plain');
463
+                // And optionally an alternative body
464
+                $this->message->addPart($msg, 'text/html');
465
+            }
466
+
467
+            if ($this->atleastonefile)
468
+            {
469
+                foreach ($filename_list as $i => $val)
470
+                {
471
+                    //$this->message->attach(Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]));
472
+                    $attachment = Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]);
473
+                    $this->message->attach($attachment);
474
+                }
475
+            }
476
+
477
+            if (! empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc));
478
+            if (! empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc));
479
+            //if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to);
480
+            if (isset($deliveryreceipt) && $deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from));
481
+        }
482
+        else
483
+        {
484
+            // Send mail method not correctly defined
485
+            // --------------------------------------
486
+            $this->error = 'Bad value for sendmode';
487
+        }
488
+    }
489
+
490
+
491
+    /**
492
+     * Send mail that was prepared by constructor.
493
+     *
494
+     * @return    boolean     True if mail sent, false otherwise
495
+     */
496
+    function sendfile()
497
+    {
498
+        global $conf,$db,$langs;
499
+
500
+        $errorlevel=error_reporting();
501
+        //error_reporting($errorlevel ^ E_WARNING);   // Desactive warnings
502
+
503
+        $res=false;
504
+
505
+        if (empty($conf->global->MAIN_DISABLE_ALL_MAILS) || !empty($conf->global->MAIN_MAIL_FORCE_SENDTO))
506
+        {
507
+            require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
508
+            $hookmanager = new HookManager($db);
509
+            $hookmanager->initHooks(array('mail'));
510
+
511
+            $parameters=array(); $action='';
512
+            $reshook = $hookmanager->executeHooks('sendMail', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
513
+            if ($reshook < 0)
514
+            {
515
+                $this->error = "Error in hook maildao sendMail " . $reshook;
516
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR);
517
+
518
+                return $reshook;
519
+            }
520
+            if ($reshook == 1)	// Hook replace standard code
521
+            {
522
+                return true;
523
+            }
524
+
525
+            // Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL
526
+            if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL=10;
527
+            $tmparray1 = explode(',', $this->addr_to);
528
+            if (count($tmparray1) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)
529
+            {
530
+                $this->error = 'Too much recipients in to:';
531
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
532
+                return false;
533
+            }
534
+            if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL=10;
535
+            $tmparray2 = explode(',', $this->addr_cc);
536
+            if (count($tmparray2) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)
537
+            {
538
+                $this->error = 'Too much recipients in cc:';
539
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
540
+                return false;
541
+            }
542
+            if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL=10;
543
+            $tmparray3 = explode(',', $this->addr_bcc);
544
+            if (count($tmparray3) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)
545
+            {
546
+                $this->error = 'Too much recipients in bcc:';
547
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
548
+                return false;
549
+            }
550
+            if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL=10;
551
+            if ((count($tmparray1)+count($tmparray2)+count($tmparray3)) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
552
+            {
553
+                $this->error = 'Too much recipients in to:, cc:, bcc:';
554
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
555
+                return false;
556
+            }
557
+
558
+            $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER';
559
+            $keyforsmtpport  ='MAIN_MAIL_SMTP_PORT';
560
+            $keyforsmtpid    ='MAIN_MAIL_SMTPS_ID';
561
+            $keyforsmtppw    ='MAIN_MAIL_SMTPS_PW';
562
+            $keyfortls       ='MAIN_MAIL_EMAIL_TLS';
563
+            $keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS';
564
+            if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
565
+            {
566
+                $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER_EMAILING';
567
+                $keyforsmtpport  ='MAIN_MAIL_SMTP_PORT_EMAILING';
568
+                $keyforsmtpid    ='MAIN_MAIL_SMTPS_ID_EMAILING';
569
+                $keyforsmtppw    ='MAIN_MAIL_SMTPS_PW_EMAILING';
570
+                $keyfortls       ='MAIN_MAIL_EMAIL_TLS_EMAILING';
571
+                $keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
572
+            }
573
+
574
+            if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO))
575
+            {
576
+                $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO;
577
+                $this->addr_cc = '';
578
+                $this->addr_bcc = '';
579
+            }
580
+
581
+            // Action according to choosed sending method
582
+            if ($this->sendmode == 'mail')
583
+            {
584
+                // Use mail php function (default PHP method)
585
+                // ------------------------------------------
586
+                dol_syslog("CMailFile::sendfile addr_to=".$this->addr_to.", subject=".$this->subject, LOG_DEBUG);
587
+                dol_syslog("CMailFile::sendfile header=\n".$this->headers, LOG_DEBUG);
588
+                //dol_syslog("CMailFile::sendfile message=\n".$message);
589
+
590
+                // If Windows, sendmail_from must be defined
591
+                if (isset($_SERVER["WINDIR"]))
592
+                {
593
+                    if (empty($this->addr_from)) $this->addr_from = '[email protected]';
594
+                    @ini_set('sendmail_from',$this->getValidAddress($this->addr_from,2));
595
+                }
596
+
597
+                // Force parameters
598
+                if (! empty($conf->global->$keyforsmtpserver)) ini_set('SMTP',$conf->global->$keyforsmtpserver);
599
+                if (! empty($conf->global->$keyforsmtpport))   ini_set('smtp_port',$conf->global->$keyforsmtpport);
600
+
601
+                $res=true;
602
+                if ($res && ! $this->subject)
603
+                {
604
+                    $this->error="Failed to send mail with php mail to HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port')."<br>Subject is empty";
605
+                    dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
606
+                    $res=false;
607
+                }
608
+                $dest=$this->getValidAddress($this->addr_to,2);
609
+                if ($res && ! $dest)
610
+                {
611
+                    $this->error="Failed to send mail with php mail to HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port')."<br>Recipient address '$dest' invalid";
612
+                    dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
613
+                    $res=false;
614
+                }
615
+
616
+                if ($res)
617
+                {
618
+                    $additionnalparam = '';	// By default
619
+                    if (! empty($conf->global->MAIN_MAIL_ALLOW_SENDMAIL_F))
620
+                    {
621
+                        // le "Return-Path" (retour des messages bounced) dans les header ne fonctionne pas avec tous les MTA
622
+                        // Le forcage de la valeur grace à l'option -f de sendmail est donc possible si la constante MAIN_MAIL_ALLOW_SENDMAIL_F est definie.
623
+                        // Having this variable defined may create problems with some sendmail (option -f refused)
624
+                        // Having this variable not defined may create problems with some other sendmail (option -f required)
625
+                        $additionnalparam .= ($additionnalparam?' ':'').(! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? '-f' . $this->getValidAddress($conf->global->MAIN_MAIL_ERRORS_TO,2) : ($this->addr_from != '' ? '-f' . $this->getValidAddress($this->addr_from,2) : '') );
626
+                    }
627
+                    if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_BA))    // To force usage of -ba option. This option tells sendmail to read From: or Sender: to setup sender
628
+                    {
629
+                        $additionnalparam .= ($additionnalparam?' ':'').'-ba';
630
+                    }
631
+
632
+                    if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_ADDPARAM)) $additionnalparam .= ($additionnalparam?' ':'').'-U '.$additionnalparam; // Use -U to add additionnal params
633
+
634
+                    dol_syslog("CMailFile::sendfile: mail start HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port').", additionnal_parameters=".$additionnalparam, LOG_DEBUG);
635
+
636
+                    $this->message=stripslashes($this->message);
637
+
638
+                    if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
639
+
640
+                    if (! empty($additionnalparam)) $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers, $additionnalparam);
641
+                    else $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers);
642
+
643
+                    if (! $res)
644
+                    {
645
+                        $langs->load("errors");
646
+                        $this->error="Failed to send mail with php mail";
647
+                        $linuxlike=1;
648
+                        if (preg_match('/^win/i',PHP_OS)) $linuxlike=0;
649
+                        if (preg_match('/^mac/i',PHP_OS)) $linuxlike=0;
650
+                        if (! $linuxlike)
651
+                        {
652
+                            $this->error.=" to HOST=".ini_get('SMTP').", PORT=".ini_get('smtp_port');	// This values are value used only for non linuxlike systems
653
+                        }
654
+                        $this->error.=".<br>";
655
+                        $this->error.=$langs->trans("ErrorPhpMailDelivery");
656
+                        dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
657
+                    }
658
+                    else
659
+                    {
660
+                        dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
661
+                    }
662
+                }
663
+
664
+                if (isset($_SERVER["WINDIR"]))
665
+                {
666
+                    @ini_restore('sendmail_from');
667
+                }
668
+
669
+                // Restore parameters
670
+                if (! empty($conf->global->$keyforsmtpserver))	ini_restore('SMTP');
671
+                if (! empty($conf->global->$keyforsmtpport)) 	ini_restore('smtp_port');
672
+            }
673
+            else if ($this->sendmode == 'smtps')
674
+            {
675
+                if (! is_object($this->smtps))
676
+                {
677
+                    $this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Constructor of object CMailFile was not initialized without errors.";
678
+                    dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
679
+                    return false;
680
+                }
681
+
682
+                // Use SMTPS library
683
+                // ------------------------------------------
684
+                $this->smtps->setTransportType(0);	// Only this method is coded in SMTPs library
685
+
686
+                // Clean parameters
687
+                if (empty($conf->global->$keyforsmtpserver)) $conf->global->$keyforsmtpserver=ini_get('SMTP');
688
+                if (empty($conf->global->$keyforsmtpport))   $conf->global->$keyforsmtpport=ini_get('smtp_port');
689
+
690
+                // If we use SSL/TLS
691
+                $server=$conf->global->$keyforsmtpserver;
692
+                $secure='';
693
+                if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $secure='ssl';
694
+                if (! empty($conf->global->$keyforstarttls) && function_exists('openssl_open')) $secure='tls';
695
+                $server=($secure?$secure.'://':'').$server;
696
+
697
+                $port=$conf->global->$keyforsmtpport;
698
+
699
+                $this->smtps->setHost($server);
700
+                $this->smtps->setPort($port); // 25, 465...;
701
+
702
+                $loginid=''; $loginpass='';
703
+                if (! empty($conf->global->$keyforsmtpid))
704
+                {
705
+                    $loginid = $conf->global->$keyforsmtpid;
706
+                    $this->smtps->setID($loginid);
707
+                }
708
+                if (! empty($conf->global->$keyforsmtppw))
709
+                {
710
+                    $loginpass = $conf->global->$keyforsmtppw;
711
+                    $this->smtps->setPW($loginpass);
712
+                }
713
+
714
+                $res=true;
715
+                $from=$this->smtps->getFrom('org');
716
+                if ($res && ! $from)
717
+                {
718
+                    $this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Sender address '$from' invalid";
719
+                    dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
720
+                    $res=false;
721
+                }
722
+                $dest=$this->smtps->getTo();
723
+                if ($res && ! $dest)
724
+                {
725
+                    $this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."<br>Recipient address '$dest' invalid";
726
+                    dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
727
+                    $res=false;
728
+                }
729
+
730
+                if ($res)
731
+                {
732
+                    if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->smtps->setDebug(true);
733
+
734
+                    $result=$this->smtps->sendMsg();
735
+                    //print $result;
736
+
737
+                    if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
738
+
739
+                    $result=$this->smtps->getErrors();
740
+                    if (empty($this->error) && empty($result))
741
+                    {
742
+                        dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
743
+                        $res=true;
744
+                    }
745
+                    else
746
+                    {
747
+                        if (empty($this->error)) $this->error=$result;
748
+                        dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
749
+                        $res=false;
750
+                    }
751
+                }
752
+            }
753
+            else if ($this->sendmode == 'swiftmailer')
754
+            {
755
+                // Use Swift Mailer library
756
+                // ------------------------------------------
757
+                require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php';
758
+
759
+                // Clean parameters
760
+                if (empty($conf->global->$keyforsmtpserver)) $conf->global->$keyforsmtpserver=ini_get('SMTP');
761
+                if (empty($conf->global->$keyforsmtpport))   $conf->global->$keyforsmtpport=ini_get('smtp_port');
762
+
763
+                // If we use SSL/TLS
764
+                $server = $conf->global->$keyforsmtpserver;
765
+                $secure = '';
766
+                if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $secure='ssl';
767
+                if (! empty($conf->global->$keyforstarttls) && function_exists('openssl_open')) $secure='tls';
768
+
769
+                $this->transport = new Swift_SmtpTransport($server, $conf->global->$keyforsmtpport, $secure);
770
+
771
+                if (! empty($conf->global->$keyforsmtpid)) $this->transport->setUsername($conf->global->$keyforsmtpid);
772
+                if (! empty($conf->global->$keyforsmtppw)) $this->transport->setPassword($conf->global->$keyforsmtppw);
773
+                //$smtps->_msgReplyTo  = '[email protected]';
774
+
775
+                // Create the Mailer using your created Transport
776
+                $this->mailer = new Swift_Mailer($this->transport);
777 777
 
778 778
                 // DKIM SIGN
779 779
                 if ($conf->global->MAIN_MAIL_EMAIL_DKIM_ENABLED) {
@@ -785,770 +785,770 @@  discard block
 block discarded – undo
785 785
                 }
786 786
 
787 787
                 if (! empty($conf->global->MAIN_MAIL_DEBUG)) {
788
-					// To use the ArrayLogger
789
-					$this->logger = new Swift_Plugins_Loggers_ArrayLogger();
790
-					// Or to use the Echo Logger
791
-					//$this->logger = new Swift_Plugins_Loggers_EchoLogger();
792
-					$this->mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this->logger));
793
-				}
794
-				// send mail
795
-				try {
796
-					$result = $this->mailer->send($this->message);
797
-				} catch (Exception $e) {
798
-					$this->error =  $e->getMessage();
799
-				}
800
-				if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
801
-
802
-				$res = true;
803
-				if (! empty($this->error) || ! $result) {
804
-					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
805
-					$res=false;
806
-				}
807
-				else
808
-				{
809
-					dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
810
-				}
811
-			}
812
-			else
813
-			{
814
-				// Send mail method not correctly defined
815
-				// --------------------------------------
816
-
817
-				return 'Bad value for sendmode';
818
-			}
819
-
820
-			$parameters=array(); $action='';
821
-			$reshook = $hookmanager->executeHooks('sendMailAfter', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
822
-			if ($reshook < 0)
823
-			{
824
-				$this->error = "Error in hook maildao sendMailAfter " . $reshook;
825
-				dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR);
826
-
827
-				return $reshook;
828
-			}
829
-		}
830
-		else
831
-		{
832
-			$this->error='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
833
-			dol_syslog("CMailFile::sendfile: ".$this->error, LOG_WARNING);
834
-		}
835
-
836
-		error_reporting($errorlevel);              // Reactive niveau erreur origine
837
-
838
-		return $res;
839
-	}
840
-
841
-	/**
842
-	 * Encode subject according to RFC 2822 - http://en.wikipedia.org/wiki/MIME#Encoded-Word
843
-	 *
844
-	 * @param string $stringtoencode String to encode
845
-	 * @return string                string encoded
846
-	 */
847
-	static function encodetorfc2822($stringtoencode)
848
-	{
849
-		global $conf;
850
-		return '=?'.$conf->file->character_set_client.'?B?'.base64_encode($stringtoencode).'?=';
851
-	}
788
+                    // To use the ArrayLogger
789
+                    $this->logger = new Swift_Plugins_Loggers_ArrayLogger();
790
+                    // Or to use the Echo Logger
791
+                    //$this->logger = new Swift_Plugins_Loggers_EchoLogger();
792
+                    $this->mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this->logger));
793
+                }
794
+                // send mail
795
+                try {
796
+                    $result = $this->mailer->send($this->message);
797
+                } catch (Exception $e) {
798
+                    $this->error =  $e->getMessage();
799
+                }
800
+                if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
801
+
802
+                $res = true;
803
+                if (! empty($this->error) || ! $result) {
804
+                    dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
805
+                    $res=false;
806
+                }
807
+                else
808
+                {
809
+                    dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
810
+                }
811
+            }
812
+            else
813
+            {
814
+                // Send mail method not correctly defined
815
+                // --------------------------------------
816
+
817
+                return 'Bad value for sendmode';
818
+            }
819
+
820
+            $parameters=array(); $action='';
821
+            $reshook = $hookmanager->executeHooks('sendMailAfter', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
822
+            if ($reshook < 0)
823
+            {
824
+                $this->error = "Error in hook maildao sendMailAfter " . $reshook;
825
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR);
826
+
827
+                return $reshook;
828
+            }
829
+        }
830
+        else
831
+        {
832
+            $this->error='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
833
+            dol_syslog("CMailFile::sendfile: ".$this->error, LOG_WARNING);
834
+        }
835
+
836
+        error_reporting($errorlevel);              // Reactive niveau erreur origine
837
+
838
+        return $res;
839
+    }
840
+
841
+    /**
842
+     * Encode subject according to RFC 2822 - http://en.wikipedia.org/wiki/MIME#Encoded-Word
843
+     *
844
+     * @param string $stringtoencode String to encode
845
+     * @return string                string encoded
846
+     */
847
+    static function encodetorfc2822($stringtoencode)
848
+    {
849
+        global $conf;
850
+        return '=?'.$conf->file->character_set_client.'?B?'.base64_encode($stringtoencode).'?=';
851
+    }
852 852
 
853 853
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
854
-	/**
855
-	 * Read a file on disk and return encoded content for emails (mode = 'mail')
856
-	 *
857
-	 * @param	string	$sourcefile		Path to file to encode
858
-	 * @return 	int					    <0 if KO, encoded string if OK
859
-	 */
860
-	function _encode_file($sourcefile)
861
-	{
854
+    /**
855
+     * Read a file on disk and return encoded content for emails (mode = 'mail')
856
+     *
857
+     * @param	string	$sourcefile		Path to file to encode
858
+     * @return 	int					    <0 if KO, encoded string if OK
859
+     */
860
+    function _encode_file($sourcefile)
861
+    {
862 862
         // phpcs:enable
863
-		$newsourcefile=dol_osencode($sourcefile);
864
-
865
-		if (is_readable($newsourcefile))
866
-		{
867
-			$contents = file_get_contents($newsourcefile);	// Need PHP 4.3
868
-			$encoded = chunk_split(base64_encode($contents), 76, $this->eol);    // 76 max is defined into http://tools.ietf.org/html/rfc2047
869
-			return $encoded;
870
-		}
871
-		else
872
-		{
873
-			$this->error="Error: Can't read file '".$sourcefile."' into _encode_file";
874
-			dol_syslog("CMailFile::encode_file: ".$this->error, LOG_ERR);
875
-			return -1;
876
-		}
877
-	}
863
+        $newsourcefile=dol_osencode($sourcefile);
864
+
865
+        if (is_readable($newsourcefile))
866
+        {
867
+            $contents = file_get_contents($newsourcefile);	// Need PHP 4.3
868
+            $encoded = chunk_split(base64_encode($contents), 76, $this->eol);    // 76 max is defined into http://tools.ietf.org/html/rfc2047
869
+            return $encoded;
870
+        }
871
+        else
872
+        {
873
+            $this->error="Error: Can't read file '".$sourcefile."' into _encode_file";
874
+            dol_syslog("CMailFile::encode_file: ".$this->error, LOG_ERR);
875
+            return -1;
876
+        }
877
+    }
878 878
 
879 879
 
880 880
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
881
-	/**
882
-	 *  Write content of a SMTP request into a dump file (mode = all)
883
-	 *  Used for debugging.
884
-	 *  Note that to see full SMTP protocol, you can use tcpdump -w /tmp/smtp -s 2000 port 25"
885
-	 *
886
-	 *  @return	void
887
-	 */
888
-	function dump_mail()
889
-	{
881
+    /**
882
+     *  Write content of a SMTP request into a dump file (mode = all)
883
+     *  Used for debugging.
884
+     *  Note that to see full SMTP protocol, you can use tcpdump -w /tmp/smtp -s 2000 port 25"
885
+     *
886
+     *  @return	void
887
+     */
888
+    function dump_mail()
889
+    {
890 890
         // phpcs:enable
891
-		global $conf,$dolibarr_main_data_root;
892
-
893
-		if (@is_writeable($dolibarr_main_data_root))	// Avoid fatal error on fopen with open_basedir
894
-		{
895
-			$outputfile=$dolibarr_main_data_root."/dolibarr_mail.log";
896
-			$fp = fopen($outputfile,"w");
897
-
898
-			if ($this->sendmode == 'mail')
899
-			{
900
-				fputs($fp, $this->headers);
901
-				fputs($fp, $this->eol);			// This eol is added by the mail function, so we add it in log
902
-				fputs($fp, $this->message);
903
-			}
904
-			elseif ($this->sendmode == 'smtps')
905
-			{
906
-				fputs($fp, $this->smtps->log);	// this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on
907
-			}
908
-			elseif ($this->sendmode == 'swiftmailer')
909
-			{
910
-				fputs($fp, $this->logger->dump());	// this->logger is filled only if MAIN_MAIL_DEBUG was set to on
911
-			}
912
-
913
-			fclose($fp);
914
-			if (! empty($conf->global->MAIN_UMASK))
915
-				@chmod($outputfile, octdec($conf->global->MAIN_UMASK));
916
-		}
917
-	}
918
-
919
-
920
-	/**
921
-	 * Correct an uncomplete html string
922
-	 *
923
-	 * @param	string	$msg	String
924
-	 * @return	string			Completed string
925
-	 */
926
-	function checkIfHTML($msg)
927
-	{
928
-		if (!preg_match('/^[\s\t]*<html/i',$msg))
929
-		{
930
-			$out = "<html><head><title></title>";
931
-			if (!empty($this->styleCSS)) $out.= $this->styleCSS;
932
-			$out.= "</head><body";
933
-			if (!empty($this->bodyCSS)) $out.= $this->bodyCSS;
934
-			$out.= ">";
935
-			$out.= $msg;
936
-			$out.= "</body></html>";
937
-		}
938
-		else
939
-		{
940
-			$out = $msg;
941
-		}
942
-
943
-		return $out;
944
-	}
945
-
946
-	/**
947
-	 * Build a css style (mode = all) into this->styleCSS and this->bodyCSS
948
-	 *
949
-	 * @return string
950
-	 */
951
-	function buildCSS()
952
-	{
953
-		if (! empty($this->css))
954
-		{
955
-			// Style CSS
956
-			$this->styleCSS = '<style type="text/css">';
957
-			$this->styleCSS.= 'body {';
958
-
959
-			if ($this->css['bgcolor'])
960
-			{
961
-				$this->styleCSS.= '  background-color: '.$this->css['bgcolor'].';';
962
-				$this->bodyCSS.= ' bgcolor="'.$this->css['bgcolor'].'"';
963
-			}
964
-			if ($this->css['bgimage'])
965
-			{
966
-				// TODO recuperer cid
967
-				$this->styleCSS.= ' background-image: url("cid:'.$this->css['bgimage_cid'].'");';
968
-			}
969
-			$this->styleCSS.= '}';
970
-			$this->styleCSS.= '</style>';
971
-		}
972
-	}
891
+        global $conf,$dolibarr_main_data_root;
892
+
893
+        if (@is_writeable($dolibarr_main_data_root))	// Avoid fatal error on fopen with open_basedir
894
+        {
895
+            $outputfile=$dolibarr_main_data_root."/dolibarr_mail.log";
896
+            $fp = fopen($outputfile,"w");
897
+
898
+            if ($this->sendmode == 'mail')
899
+            {
900
+                fputs($fp, $this->headers);
901
+                fputs($fp, $this->eol);			// This eol is added by the mail function, so we add it in log
902
+                fputs($fp, $this->message);
903
+            }
904
+            elseif ($this->sendmode == 'smtps')
905
+            {
906
+                fputs($fp, $this->smtps->log);	// this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on
907
+            }
908
+            elseif ($this->sendmode == 'swiftmailer')
909
+            {
910
+                fputs($fp, $this->logger->dump());	// this->logger is filled only if MAIN_MAIL_DEBUG was set to on
911
+            }
912
+
913
+            fclose($fp);
914
+            if (! empty($conf->global->MAIN_UMASK))
915
+                @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
916
+        }
917
+    }
918
+
919
+
920
+    /**
921
+     * Correct an uncomplete html string
922
+     *
923
+     * @param	string	$msg	String
924
+     * @return	string			Completed string
925
+     */
926
+    function checkIfHTML($msg)
927
+    {
928
+        if (!preg_match('/^[\s\t]*<html/i',$msg))
929
+        {
930
+            $out = "<html><head><title></title>";
931
+            if (!empty($this->styleCSS)) $out.= $this->styleCSS;
932
+            $out.= "</head><body";
933
+            if (!empty($this->bodyCSS)) $out.= $this->bodyCSS;
934
+            $out.= ">";
935
+            $out.= $msg;
936
+            $out.= "</body></html>";
937
+        }
938
+        else
939
+        {
940
+            $out = $msg;
941
+        }
942
+
943
+        return $out;
944
+    }
945
+
946
+    /**
947
+     * Build a css style (mode = all) into this->styleCSS and this->bodyCSS
948
+     *
949
+     * @return string
950
+     */
951
+    function buildCSS()
952
+    {
953
+        if (! empty($this->css))
954
+        {
955
+            // Style CSS
956
+            $this->styleCSS = '<style type="text/css">';
957
+            $this->styleCSS.= 'body {';
958
+
959
+            if ($this->css['bgcolor'])
960
+            {
961
+                $this->styleCSS.= '  background-color: '.$this->css['bgcolor'].';';
962
+                $this->bodyCSS.= ' bgcolor="'.$this->css['bgcolor'].'"';
963
+            }
964
+            if ($this->css['bgimage'])
965
+            {
966
+                // TODO recuperer cid
967
+                $this->styleCSS.= ' background-image: url("cid:'.$this->css['bgimage_cid'].'");';
968
+            }
969
+            $this->styleCSS.= '}';
970
+            $this->styleCSS.= '</style>';
971
+        }
972
+    }
973 973
 
974 974
 
975 975
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
976
-	/**
977
-	 * Create SMTP headers (mode = 'mail')
978
-	 *
979
-	 * @return	string headers
980
-	 */
981
-	function write_smtpheaders()
982
-	{
976
+    /**
977
+     * Create SMTP headers (mode = 'mail')
978
+     *
979
+     * @return	string headers
980
+     */
981
+    function write_smtpheaders()
982
+    {
983 983
         // phpcs:enable
984
-		global $conf;
985
-		$out = "";
984
+        global $conf;
985
+        $out = "";
986 986
 
987
-		$host = dol_getprefix('email');
987
+        $host = dol_getprefix('email');
988 988
 
989
-		// Sender
990
-		//$out.= "Sender: ".getValidAddress($this->addr_from,2)).$this->eol2;
991
-		$out.= "From: ".$this->getValidAddress($this->addr_from,3,1).$this->eol2;
992
-		if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_BA))
993
-		{
994
-			$out.= "To: ".$this->getValidAddress($this->addr_to,0,1).$this->eol2;
995
-		}
996
-		// Return-Path is important because it is used by SPF. Some MTA does not read Return-Path from header but from command line. See option MAIN_MAIL_ALLOW_SENDMAIL_F for that.
997
-		$out.= "Return-Path: ".$this->getValidAddress($this->addr_from,0,1).$this->eol2;
998
-		if (isset($this->reply_to)  && $this->reply_to)  $out.= "Reply-To: ".$this->getValidAddress($this->reply_to,2).$this->eol2;
999
-		if (isset($this->errors_to) && $this->errors_to) $out.= "Errors-To: ".$this->getValidAddress($this->errors_to,2).$this->eol2;
989
+        // Sender
990
+        //$out.= "Sender: ".getValidAddress($this->addr_from,2)).$this->eol2;
991
+        $out.= "From: ".$this->getValidAddress($this->addr_from,3,1).$this->eol2;
992
+        if (! empty($conf->global->MAIN_MAIL_SENDMAIL_FORCE_BA))
993
+        {
994
+            $out.= "To: ".$this->getValidAddress($this->addr_to,0,1).$this->eol2;
995
+        }
996
+        // Return-Path is important because it is used by SPF. Some MTA does not read Return-Path from header but from command line. See option MAIN_MAIL_ALLOW_SENDMAIL_F for that.
997
+        $out.= "Return-Path: ".$this->getValidAddress($this->addr_from,0,1).$this->eol2;
998
+        if (isset($this->reply_to)  && $this->reply_to)  $out.= "Reply-To: ".$this->getValidAddress($this->reply_to,2).$this->eol2;
999
+        if (isset($this->errors_to) && $this->errors_to) $out.= "Errors-To: ".$this->getValidAddress($this->errors_to,2).$this->eol2;
1000 1000
 
1001
-		// Receiver
1002
-		if (isset($this->addr_cc)   && $this->addr_cc)   $out.= "Cc: ".$this->getValidAddress($this->addr_cc,2).$this->eol2;
1003
-		if (isset($this->addr_bcc)  && $this->addr_bcc)  $out.= "Bcc: ".$this->getValidAddress($this->addr_bcc,2).$this->eol2;    // TODO Question: bcc must not be into header, only into SMTP command "RCPT TO". Does php mail support this ?
1001
+        // Receiver
1002
+        if (isset($this->addr_cc)   && $this->addr_cc)   $out.= "Cc: ".$this->getValidAddress($this->addr_cc,2).$this->eol2;
1003
+        if (isset($this->addr_bcc)  && $this->addr_bcc)  $out.= "Bcc: ".$this->getValidAddress($this->addr_bcc,2).$this->eol2;    // TODO Question: bcc must not be into header, only into SMTP command "RCPT TO". Does php mail support this ?
1004 1004
 
1005
-		// Delivery receipt
1006
-		if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $out.= "Disposition-Notification-To: ".$this->getValidAddress($this->addr_from,2).$this->eol2;
1005
+        // Delivery receipt
1006
+        if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $out.= "Disposition-Notification-To: ".$this->getValidAddress($this->addr_from,2).$this->eol2;
1007 1007
 
1008
-		//$out.= "X-Priority: 3".$this->eol2;
1008
+        //$out.= "X-Priority: 3".$this->eol2;
1009 1009
 
1010
-		$out.= 'Date: ' . date("r") . $this->eol2;
1010
+        $out.= 'Date: ' . date("r") . $this->eol2;
1011 1011
 
1012
-		$trackid = $this->trackid;
1013
-		if ($trackid)
1014
-		{
1015
-			// References is kept in response and Message-ID is returned into In-Reply-To:
1016
-			$out.= 'Message-ID: <' . time() . '.phpmail-dolibarr-'. $trackid . '@' . $host . ">" . $this->eol2;	// Uppercase seems replaced by phpmail
1017
-			$out.= 'References: <' . time() . '.phpmail-dolibarr-'. $trackid . '@' . $host . ">" . $this->eol2;
1018
-			$out.= 'X-Dolibarr-TRACKID: ' . $trackid . '@' . $host. $this->eol2;
1019
-		}
1020
-		else
1021
-		{
1022
-			$out.= 'Message-ID: <' . time() . '.phpmail@' . $host . ">" . $this->eol2;
1023
-		}
1012
+        $trackid = $this->trackid;
1013
+        if ($trackid)
1014
+        {
1015
+            // References is kept in response and Message-ID is returned into In-Reply-To:
1016
+            $out.= 'Message-ID: <' . time() . '.phpmail-dolibarr-'. $trackid . '@' . $host . ">" . $this->eol2;	// Uppercase seems replaced by phpmail
1017
+            $out.= 'References: <' . time() . '.phpmail-dolibarr-'. $trackid . '@' . $host . ">" . $this->eol2;
1018
+            $out.= 'X-Dolibarr-TRACKID: ' . $trackid . '@' . $host. $this->eol2;
1019
+        }
1020
+        else
1021
+        {
1022
+            $out.= 'Message-ID: <' . time() . '.phpmail@' . $host . ">" . $this->eol2;
1023
+        }
1024 1024
 
1025
-		if (! empty($_SERVER['REMOTE_ADDR'])) $out.= "X-RemoteAddr: " . $_SERVER['REMOTE_ADDR']. $this->eol2;
1026
-		$out.= "X-Mailer: Dolibarr version " . DOL_VERSION ." (using php mail)".$this->eol2;
1027
-		$out.= "Mime-Version: 1.0".$this->eol2;
1025
+        if (! empty($_SERVER['REMOTE_ADDR'])) $out.= "X-RemoteAddr: " . $_SERVER['REMOTE_ADDR']. $this->eol2;
1026
+        $out.= "X-Mailer: Dolibarr version " . DOL_VERSION ." (using php mail)".$this->eol2;
1027
+        $out.= "Mime-Version: 1.0".$this->eol2;
1028 1028
 
1029
-		//$out.= "From: ".$this->getValidAddress($this->addr_from,3,1).$this->eol;
1029
+        //$out.= "From: ".$this->getValidAddress($this->addr_from,3,1).$this->eol;
1030 1030
 
1031
-		$out.= "Content-Type: multipart/mixed;".$this->eol2." boundary=\"".$this->mixed_boundary."\"".$this->eol2;
1032
-		$out.= "Content-Transfer-Encoding: 8bit".$this->eol2;		// TODO Seems to be ignored. Header is 7bit once received.
1031
+        $out.= "Content-Type: multipart/mixed;".$this->eol2." boundary=\"".$this->mixed_boundary."\"".$this->eol2;
1032
+        $out.= "Content-Transfer-Encoding: 8bit".$this->eol2;		// TODO Seems to be ignored. Header is 7bit once received.
1033 1033
 
1034
-		dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out);
1035
-		return $out;
1036
-	}
1034
+        dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out);
1035
+        return $out;
1036
+    }
1037 1037
 
1038 1038
 
1039 1039
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1040
-	/**
1041
-	 * Create header MIME (mode = 'mail')
1042
-	 *
1043
-	 * @param	array	$filename_list			Array of filenames
1044
-	 * @param 	array	$mimefilename_list		Array of mime types
1045
-	 * @return	string							mime headers
1046
-	 */
1047
-	function write_mimeheaders($filename_list, $mimefilename_list)
1048
-	{
1040
+    /**
1041
+     * Create header MIME (mode = 'mail')
1042
+     *
1043
+     * @param	array	$filename_list			Array of filenames
1044
+     * @param 	array	$mimefilename_list		Array of mime types
1045
+     * @return	string							mime headers
1046
+     */
1047
+    function write_mimeheaders($filename_list, $mimefilename_list)
1048
+    {
1049 1049
         // phpcs:enable
1050
-		$mimedone=0;
1051
-		$out = "";
1052
-
1053
-		if (is_array($filename_list))
1054
-		{
1055
-			$filename_list_size=count($filename_list);
1056
-			for($i=0;$i < $filename_list_size;$i++)
1057
-			{
1058
-				if ($filename_list[$i])
1059
-				{
1060
-					if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
1061
-					$out.= "X-attachments: $filename_list[$i]".$this->eol2;
1062
-				}
1063
-			}
1064
-		}
1065
-
1066
-		dol_syslog("CMailFile::write_mimeheaders mime_header=\n".$out, LOG_DEBUG);
1067
-		return $out;
1068
-	}
1050
+        $mimedone=0;
1051
+        $out = "";
1052
+
1053
+        if (is_array($filename_list))
1054
+        {
1055
+            $filename_list_size=count($filename_list);
1056
+            for($i=0;$i < $filename_list_size;$i++)
1057
+            {
1058
+                if ($filename_list[$i])
1059
+                {
1060
+                    if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
1061
+                    $out.= "X-attachments: $filename_list[$i]".$this->eol2;
1062
+                }
1063
+            }
1064
+        }
1069 1065
 
1070
-    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1071
-	/**
1072
-	 * Return email content (mode = 'mail')
1073
-	 *
1074
-	 * @param	string		$msgtext		Message string
1075
-	 * @return	string						String content
1076
-	 */
1077
-	function write_body($msgtext)
1078
-	{
1079
-        // phpcs:enable
1080
-		global $conf;
1081
-
1082
-		$out='';
1083
-
1084
-		$out.= "--" . $this->mixed_boundary . $this->eol;
1085
-
1086
-		if ($this->atleastoneimage)
1087
-		{
1088
-			$out.= "Content-Type: multipart/alternative;".$this->eol." boundary=\"".$this->alternative_boundary."\"".$this->eol;
1089
-			$out.= $this->eol;
1090
-			$out.= "--" . $this->alternative_boundary . $this->eol;
1091
-		}
1092
-
1093
-		// Make RFC821 Compliant, replace bare linefeeds
1094
-		$strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $msgtext);	// PCRE modifier /s means new lines are common chars
1095
-		if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
1096
-		{
1097
-			$strContent = preg_replace("/\r\n/si", "\n", $strContent);	// PCRE modifier /s means new lines are common chars
1098
-		}
1099
-
1100
-		$strContentAltText = '';
1101
-		if ($this->msgishtml)
1102
-		{
1103
-			// Similar code to forge a text from html is also in CMailFile.class.php
1104
-			$strContentAltText = preg_replace("/<br\s*[^>]*>/"," ", $strContent);
1105
-			$strContentAltText = html_entity_decode(strip_tags($strContentAltText));
1106
-			$strContentAltText = rtrim(wordwrap($strContentAltText, 75, empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)?"\r\n":"\n"));
1107
-
1108
-			// Check if html header already in message, if not complete the message
1109
-			$strContent = $this->checkIfHTML($strContent);
1110
-		}
1111
-
1112
-		// Make RFC2045 Compliant, split lines
1113
-		//$strContent = rtrim(chunk_split($strContent));    // Function chunck_split seems ko if not used on a base64 content
1114
-		// TODO Encode main content into base64 and use the chunk_split, or quoted-printable
1115
-		$strContent = rtrim(wordwrap($strContent, 75, empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)?"\r\n":"\n"));   // TODO Using this method creates unexpected line break on text/plain content.
1116
-
1117
-		if ($this->msgishtml)
1118
-		{
1119
-			if ($this->atleastoneimage)
1120
-			{
1121
-				$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
1122
-				//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
1123
-				$out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message
1124
-				$out.= "--" . $this->alternative_boundary . $this->eol;
1125
-				$out.= "Content-Type: multipart/related;".$this->eol." boundary=\"".$this->related_boundary."\"".$this->eol;
1126
-				$out.= $this->eol;
1127
-				$out.= "--" . $this->related_boundary . $this->eol;
1128
-			}
1129
-
1130
-			if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))    // Add plain text message part before html part
1131
-			{
1132
-				$out.= "Content-Type: multipart/alternative;".$this->eol." boundary=\"".$this->alternative_boundary."\"".$this->eol;
1133
-				$out.= $this->eol;
1134
-				$out.= "--" . $this->alternative_boundary . $this->eol;
1135
-				$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
1136
-				//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
1137
-				$out.= $this->eol.$strContentAltText.$this->eol;
1138
-				$out.= "--" . $this->alternative_boundary . $this->eol;
1139
-			}
1140
-
1141
-			$out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol;
1142
-			//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;	// TODO Use base64
1143
-			$out.= $this->eol.$strContent.$this->eol;
1144
-
1145
-			if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))    // Add plain text message part after html part
1146
-			{
1147
-				$out.= "--" . $this->alternative_boundary . "--". $this->eol;
1148
-			}
1149
-		}
1150
-		else
1151
-		{
1152
-			$out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
1153
-			//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
1154
-			$out.= $this->eol.$strContent.$this->eol;
1155
-		}
1156
-
1157
-		$out.= $this->eol;
1158
-
1159
-		// Encode images
1160
-		if ($this->atleastoneimage)
1161
-		{
1162
-			$out .= $this->write_images($this->images_encoded);
1163
-			// always end related and end alternative after inline images
1164
-			$out .= "--" . $this->related_boundary . "--" . $this->eol;
1165
-			$out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol;
1166
-			$out .= $this->eol;
1167
-		}
1168
-
1169
-		return $out;
1170
-	}
1066
+        dol_syslog("CMailFile::write_mimeheaders mime_header=\n".$out, LOG_DEBUG);
1067
+        return $out;
1068
+    }
1171 1069
 
1172 1070
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1173
-	/**
1174
-	 * Attach file to email (mode = 'mail')
1175
-	 *
1176
-	 * @param	array	$filename_list		Tableau
1177
-	 * @param	array	$mimetype_list		Tableau
1178
-	 * @param 	array	$mimefilename_list	Tableau
1179
-	 * @return	string						Chaine fichiers encodes
1180
-	 */
1181
-	function write_files($filename_list,$mimetype_list,$mimefilename_list)
1182
-	{
1071
+    /**
1072
+     * Return email content (mode = 'mail')
1073
+     *
1074
+     * @param	string		$msgtext		Message string
1075
+     * @return	string						String content
1076
+     */
1077
+    function write_body($msgtext)
1078
+    {
1183 1079
         // phpcs:enable
1184
-		$out = '';
1185
-
1186
-		$filename_list_size=count($filename_list);
1187
-		for($i=0;$i < $filename_list_size;$i++)
1188
-		{
1189
-			if ($filename_list[$i])
1190
-			{
1191
-				dol_syslog("CMailFile::write_files: i=$i");
1192
-				$encoded = $this->_encode_file($filename_list[$i]);
1193
-				if ($encoded >= 0)
1194
-				{
1195
-					if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
1196
-					if (! $mimetype_list[$i]) {
1197
-						$mimetype_list[$i] = "application/octet-stream";
1198
-					}
1199
-
1200
-					$out.= "--" . $this->mixed_boundary . $this->eol;
1201
-					$out.= "Content-Disposition: attachment; filename=\"".$filename_list[$i]."\"".$this->eol;
1202
-					$out.= "Content-Type: " . $mimetype_list[$i] . "; name=\"".$filename_list[$i]."\"".$this->eol;
1203
-					$out.= "Content-Transfer-Encoding: base64".$this->eol;
1204
-					$out.= "Content-Description: ".$filename_list[$i].$this->eol;
1205
-					$out.= $this->eol;
1206
-					$out.= $encoded;
1207
-					$out.= $this->eol;
1208
-					//$out.= $this->eol;
1209
-				}
1210
-				else
1211
-				{
1212
-					return $encoded;
1213
-				}
1214
-			}
1215
-		}
1216
-
1217
-		return $out;
1218
-	}
1080
+        global $conf;
1081
+
1082
+        $out='';
1083
+
1084
+        $out.= "--" . $this->mixed_boundary . $this->eol;
1085
+
1086
+        if ($this->atleastoneimage)
1087
+        {
1088
+            $out.= "Content-Type: multipart/alternative;".$this->eol." boundary=\"".$this->alternative_boundary."\"".$this->eol;
1089
+            $out.= $this->eol;
1090
+            $out.= "--" . $this->alternative_boundary . $this->eol;
1091
+        }
1092
+
1093
+        // Make RFC821 Compliant, replace bare linefeeds
1094
+        $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $msgtext);	// PCRE modifier /s means new lines are common chars
1095
+        if (! empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
1096
+        {
1097
+            $strContent = preg_replace("/\r\n/si", "\n", $strContent);	// PCRE modifier /s means new lines are common chars
1098
+        }
1099
+
1100
+        $strContentAltText = '';
1101
+        if ($this->msgishtml)
1102
+        {
1103
+            // Similar code to forge a text from html is also in CMailFile.class.php
1104
+            $strContentAltText = preg_replace("/<br\s*[^>]*>/"," ", $strContent);
1105
+            $strContentAltText = html_entity_decode(strip_tags($strContentAltText));
1106
+            $strContentAltText = rtrim(wordwrap($strContentAltText, 75, empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)?"\r\n":"\n"));
1107
+
1108
+            // Check if html header already in message, if not complete the message
1109
+            $strContent = $this->checkIfHTML($strContent);
1110
+        }
1111
+
1112
+        // Make RFC2045 Compliant, split lines
1113
+        //$strContent = rtrim(chunk_split($strContent));    // Function chunck_split seems ko if not used on a base64 content
1114
+        // TODO Encode main content into base64 and use the chunk_split, or quoted-printable
1115
+        $strContent = rtrim(wordwrap($strContent, 75, empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)?"\r\n":"\n"));   // TODO Using this method creates unexpected line break on text/plain content.
1116
+
1117
+        if ($this->msgishtml)
1118
+        {
1119
+            if ($this->atleastoneimage)
1120
+            {
1121
+                $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
1122
+                //$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
1123
+                $out.= $this->eol.($strContentAltText?$strContentAltText:strip_tags($strContent)).$this->eol; // Add plain text message
1124
+                $out.= "--" . $this->alternative_boundary . $this->eol;
1125
+                $out.= "Content-Type: multipart/related;".$this->eol." boundary=\"".$this->related_boundary."\"".$this->eol;
1126
+                $out.= $this->eol;
1127
+                $out.= "--" . $this->related_boundary . $this->eol;
1128
+            }
1129
+
1130
+            if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))    // Add plain text message part before html part
1131
+            {
1132
+                $out.= "Content-Type: multipart/alternative;".$this->eol." boundary=\"".$this->alternative_boundary."\"".$this->eol;
1133
+                $out.= $this->eol;
1134
+                $out.= "--" . $this->alternative_boundary . $this->eol;
1135
+                $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
1136
+                //$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
1137
+                $out.= $this->eol.$strContentAltText.$this->eol;
1138
+                $out.= "--" . $this->alternative_boundary . $this->eol;
1139
+            }
1140
+
1141
+            $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol;
1142
+            //$out.= "Content-Transfer-Encoding: 7bit".$this->eol;	// TODO Use base64
1143
+            $out.= $this->eol.$strContent.$this->eol;
1219 1144
 
1145
+            if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))    // Add plain text message part after html part
1146
+            {
1147
+                $out.= "--" . $this->alternative_boundary . "--". $this->eol;
1148
+            }
1149
+        }
1150
+        else
1151
+        {
1152
+            $out.= "Content-Type: text/plain; charset=".$conf->file->character_set_client.$this->eol;
1153
+            //$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
1154
+            $out.= $this->eol.$strContent.$this->eol;
1155
+        }
1156
+
1157
+        $out.= $this->eol;
1158
+
1159
+        // Encode images
1160
+        if ($this->atleastoneimage)
1161
+        {
1162
+            $out .= $this->write_images($this->images_encoded);
1163
+            // always end related and end alternative after inline images
1164
+            $out .= "--" . $this->related_boundary . "--" . $this->eol;
1165
+            $out .= $this->eol . "--" . $this->alternative_boundary . "--" . $this->eol;
1166
+            $out .= $this->eol;
1167
+        }
1168
+
1169
+        return $out;
1170
+    }
1220 1171
 
1221 1172
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1222
-	/**
1223
-	 * Attach an image to email (mode = 'mail')
1224
-	 *
1225
-	 * @param	array	$images_list	Array of array image
1226
-	 * @return	string					Chaine images encodees
1227
-	 */
1228
-	function write_images($images_list)
1229
-	{
1173
+    /**
1174
+     * Attach file to email (mode = 'mail')
1175
+     *
1176
+     * @param	array	$filename_list		Tableau
1177
+     * @param	array	$mimetype_list		Tableau
1178
+     * @param 	array	$mimefilename_list	Tableau
1179
+     * @return	string						Chaine fichiers encodes
1180
+     */
1181
+    function write_files($filename_list,$mimetype_list,$mimefilename_list)
1182
+    {
1230 1183
         // phpcs:enable
1231
-		$out = '';
1184
+        $out = '';
1185
+
1186
+        $filename_list_size=count($filename_list);
1187
+        for($i=0;$i < $filename_list_size;$i++)
1188
+        {
1189
+            if ($filename_list[$i])
1190
+            {
1191
+                dol_syslog("CMailFile::write_files: i=$i");
1192
+                $encoded = $this->_encode_file($filename_list[$i]);
1193
+                if ($encoded >= 0)
1194
+                {
1195
+                    if ($mimefilename_list[$i]) $filename_list[$i] = $mimefilename_list[$i];
1196
+                    if (! $mimetype_list[$i]) {
1197
+                        $mimetype_list[$i] = "application/octet-stream";
1198
+                    }
1199
+
1200
+                    $out.= "--" . $this->mixed_boundary . $this->eol;
1201
+                    $out.= "Content-Disposition: attachment; filename=\"".$filename_list[$i]."\"".$this->eol;
1202
+                    $out.= "Content-Type: " . $mimetype_list[$i] . "; name=\"".$filename_list[$i]."\"".$this->eol;
1203
+                    $out.= "Content-Transfer-Encoding: base64".$this->eol;
1204
+                    $out.= "Content-Description: ".$filename_list[$i].$this->eol;
1205
+                    $out.= $this->eol;
1206
+                    $out.= $encoded;
1207
+                    $out.= $this->eol;
1208
+                    //$out.= $this->eol;
1209
+                }
1210
+                else
1211
+                {
1212
+                    return $encoded;
1213
+                }
1214
+            }
1215
+        }
1232 1216
 
1233
-		if (is_array($images_list))
1234
-		{
1235
-			foreach ($images_list as $img)
1236
-			{
1237
-				dol_syslog("CMailFile::write_images: ".$img["name"]);
1217
+        return $out;
1218
+    }
1238 1219
 
1239
-				$out.= "--" . $this->related_boundary . $this->eol; // always related for an inline image
1240
-				$out.= "Content-Type: " . $img["content_type"] . "; name=\"".$img["name"]."\"".$this->eol;
1241
-				$out.= "Content-Transfer-Encoding: base64".$this->eol;
1242
-				$out.= "Content-Disposition: inline; filename=\"".$img["name"]."\"".$this->eol;
1243
-				$out.= "Content-ID: <".$img["cid"].">".$this->eol;
1244
-				$out.= $this->eol;
1245
-				$out.= $img["image_encoded"];
1246
-				$out.= $this->eol;
1247
-			}
1248
-		}
1249 1220
 
1250
-		return $out;
1251
-	}
1221
+    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1222
+    /**
1223
+     * Attach an image to email (mode = 'mail')
1224
+     *
1225
+     * @param	array	$images_list	Array of array image
1226
+     * @return	string					Chaine images encodees
1227
+     */
1228
+    function write_images($images_list)
1229
+    {
1230
+        // phpcs:enable
1231
+        $out = '';
1232
+
1233
+        if (is_array($images_list))
1234
+        {
1235
+            foreach ($images_list as $img)
1236
+            {
1237
+                dol_syslog("CMailFile::write_images: ".$img["name"]);
1238
+
1239
+                $out.= "--" . $this->related_boundary . $this->eol; // always related for an inline image
1240
+                $out.= "Content-Type: " . $img["content_type"] . "; name=\"".$img["name"]."\"".$this->eol;
1241
+                $out.= "Content-Transfer-Encoding: base64".$this->eol;
1242
+                $out.= "Content-Disposition: inline; filename=\"".$img["name"]."\"".$this->eol;
1243
+                $out.= "Content-ID: <".$img["cid"].">".$this->eol;
1244
+                $out.= $this->eol;
1245
+                $out.= $img["image_encoded"];
1246
+                $out.= $this->eol;
1247
+            }
1248
+        }
1249
+
1250
+        return $out;
1251
+    }
1252 1252
 
1253 1253
 
1254 1254
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1255
-	/**
1256
-	 * Try to create a socket connection
1257
-	 *
1258
-	 * @param 	string		$host		Add ssl:// for SSL/TLS.
1259
-	 * @param 	int			$port		Example: 25, 465
1260
-	 * @return	int						Socket id if ok, 0 if KO
1261
-	 */
1262
-	function check_server_port($host,$port)
1263
-	{
1255
+    /**
1256
+     * Try to create a socket connection
1257
+     *
1258
+     * @param 	string		$host		Add ssl:// for SSL/TLS.
1259
+     * @param 	int			$port		Example: 25, 465
1260
+     * @return	int						Socket id if ok, 0 if KO
1261
+     */
1262
+    function check_server_port($host,$port)
1263
+    {
1264 1264
         // phpcs:enable
1265
-		global $conf;
1266
-
1267
-		$_retVal=0;
1268
-		$timeout=5;	// Timeout in seconds
1269
-
1270
-		if (function_exists('fsockopen'))
1271
-		{
1272
-			$keyforsmtpserver='MAIN_MAIL_SMTP_SERVER';
1273
-			$keyforsmtpport  ='MAIN_MAIL_SMTP_PORT';
1274
-			$keyforsmtpid    ='MAIN_MAIL_SMTPS_ID';
1275
-			$keyforsmtppw    ='MAIN_MAIL_SMTPS_PW';
1276
-			$keyfortls       ='MAIN_MAIL_EMAIL_TLS';
1277
-			$keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS';
1278
-			if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
1279
-			{
1280
-				$keyforsmtpserver='MAIN_MAIL_SMTP_SERVER_EMAILING';
1281
-				$keyforsmtpport  ='MAIN_MAIL_SMTP_PORT_EMAILING';
1282
-				$keyforsmtpid    ='MAIN_MAIL_SMTPS_ID_EMAILING';
1283
-				$keyforsmtppw    ='MAIN_MAIL_SMTPS_PW_EMAILING';
1284
-				$keyfortls       ='MAIN_MAIL_EMAIL_TLS_EMAILING';
1285
-				$keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
1286
-			}
1287
-
1288
-			// If we use SSL/TLS
1289
-			if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $host='ssl://'.$host;
1290
-			// tls smtp start with no encryption
1291
-			//if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $host='tls://'.$host;
1292
-
1293
-			dol_syslog("Try socket connection to host=".$host." port=".$port);
1294
-			//See if we can connect to the SMTP server
1295
-			if ($socket = @fsockopen(
1296
-					$host,       // Host to test, IP or domain. Add ssl:// for SSL/TLS.
1297
-					$port,       // which Port number to use
1298
-					$errno,      // actual system level error
1299
-					$errstr,     // and any text that goes with the error
1300
-					$timeout
1301
-			))  // timeout for reading/writing data over the socket
1302
-			{
1303
-				// Windows still does not have support for this timeout function
1304
-				if (function_exists('stream_set_timeout')) stream_set_timeout($socket, $timeout, 0);
1305
-
1306
-				dol_syslog("Now we wait for answer 220");
1307
-
1308
-				// Check response from Server
1309
-				if ( $_retVal = $this->server_parse($socket, "220") ) $_retVal = $socket;
1310
-			}
1311
-			else
1312
-			{
1313
-				$this->error = utf8_check('Error '.$errno.' - '.$errstr)?'Error '.$errno.' - '.$errstr:utf8_encode('Error '.$errno.' - '.$errstr);
1314
-			}
1315
-		}
1316
-		return $_retVal;
1317
-	}
1265
+        global $conf;
1266
+
1267
+        $_retVal=0;
1268
+        $timeout=5;	// Timeout in seconds
1269
+
1270
+        if (function_exists('fsockopen'))
1271
+        {
1272
+            $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER';
1273
+            $keyforsmtpport  ='MAIN_MAIL_SMTP_PORT';
1274
+            $keyforsmtpid    ='MAIN_MAIL_SMTPS_ID';
1275
+            $keyforsmtppw    ='MAIN_MAIL_SMTPS_PW';
1276
+            $keyfortls       ='MAIN_MAIL_EMAIL_TLS';
1277
+            $keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS';
1278
+            if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
1279
+            {
1280
+                $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER_EMAILING';
1281
+                $keyforsmtpport  ='MAIN_MAIL_SMTP_PORT_EMAILING';
1282
+                $keyforsmtpid    ='MAIN_MAIL_SMTPS_ID_EMAILING';
1283
+                $keyforsmtppw    ='MAIN_MAIL_SMTPS_PW_EMAILING';
1284
+                $keyfortls       ='MAIN_MAIL_EMAIL_TLS_EMAILING';
1285
+                $keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
1286
+            }
1287
+
1288
+            // If we use SSL/TLS
1289
+            if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $host='ssl://'.$host;
1290
+            // tls smtp start with no encryption
1291
+            //if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $host='tls://'.$host;
1292
+
1293
+            dol_syslog("Try socket connection to host=".$host." port=".$port);
1294
+            //See if we can connect to the SMTP server
1295
+            if ($socket = @fsockopen(
1296
+                    $host,       // Host to test, IP or domain. Add ssl:// for SSL/TLS.
1297
+                    $port,       // which Port number to use
1298
+                    $errno,      // actual system level error
1299
+                    $errstr,     // and any text that goes with the error
1300
+                    $timeout
1301
+            ))  // timeout for reading/writing data over the socket
1302
+            {
1303
+                // Windows still does not have support for this timeout function
1304
+                if (function_exists('stream_set_timeout')) stream_set_timeout($socket, $timeout, 0);
1305
+
1306
+                dol_syslog("Now we wait for answer 220");
1307
+
1308
+                // Check response from Server
1309
+                if ( $_retVal = $this->server_parse($socket, "220") ) $_retVal = $socket;
1310
+            }
1311
+            else
1312
+            {
1313
+                $this->error = utf8_check('Error '.$errno.' - '.$errstr)?'Error '.$errno.' - '.$errstr:utf8_encode('Error '.$errno.' - '.$errstr);
1314
+            }
1315
+        }
1316
+        return $_retVal;
1317
+    }
1318 1318
 
1319 1319
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1320
-	/**
1321
-	 * This function has been modified as provided by SirSir to allow multiline responses when
1322
-	 * using SMTP Extensions.
1323
-	 *
1324
-	 * @param	Socket	$socket			Socket
1325
-	 * @param   string	$response		Response string
1326
-	 * @return  boolean					true if success
1327
-	 */
1328
-	function server_parse($socket, $response)
1329
-	{
1320
+    /**
1321
+     * This function has been modified as provided by SirSir to allow multiline responses when
1322
+     * using SMTP Extensions.
1323
+     *
1324
+     * @param	Socket	$socket			Socket
1325
+     * @param   string	$response		Response string
1326
+     * @return  boolean					true if success
1327
+     */
1328
+    function server_parse($socket, $response)
1329
+    {
1330 1330
         // phpcs:enable
1331
-		$_retVal = true;	// Indicates if Object was created or not
1332
-		$server_response = '';
1333
-
1334
-		while (substr($server_response,3,1) != ' ')
1335
-		{
1336
-			if (! ($server_response = fgets($socket, 256)) )
1337
-			{
1338
-				$this->error="Couldn't get mail server response codes";
1339
-				return false;
1340
-			}
1341
-		}
1342
-
1343
-		if( !( substr($server_response, 0, 3) == $response ) )
1344
-		{
1345
-			$this->error="Ran into problems sending Mail.\r\nResponse: $server_response";
1346
-			$_retVal = false;
1347
-		}
1348
-
1349
-		return $_retVal;
1350
-	}
1351
-
1352
-	/**
1353
-	 * Seearch images into html message and init array this->images_encoded if found
1354
-	 *
1355
-	 * @param	string	$images_dir		Location of physical images files
1356
-	 * @return	int 		        	>0 if OK, <0 if KO
1357
-	 */
1358
-	function findHtmlImages($images_dir)
1359
-	{
1360
-		// Build the list of image extensions
1361
-		$extensions = array_keys($this->image_types);
1362
-
1363
-		$matches = array();
1364
-		preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches);  // If "xxx.ext" or 'xxx.ext' found
1365
-
1366
-		if (! empty($matches))
1367
-		{
1368
-			$i=0;
1369
-			foreach ($matches[1] as $full)
1370
-			{
1371
-
1372
-				if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs))   // If xxx is 'file=aaa'
1373
-				{
1374
-					$img = $regs[1];
1375
-
1376
-					if (file_exists($images_dir.'/'.$img))
1377
-					{
1378
-						// Image path in src
1379
-						$src = preg_quote($full,'/');
1380
-
1381
-						// Image full path
1382
-						$this->html_images[$i]["fullpath"] = $images_dir.'/'.$img;
1383
-
1384
-						// Image name
1385
-						$this->html_images[$i]["name"] = $img;
1386
-
1387
-						// Content type
1388
-						if (preg_match('/^.+\.(\w{3,4})$/', $img, $reg))
1389
-						{
1390
-							$ext=strtolower($reg[1]);
1391
-							$this->html_images[$i]["content_type"] = $this->image_types[$ext];
1392
-						}
1393
-
1394
-						// cid
1395
-						$this->html_images[$i]["cid"] = dol_hash(uniqid(time()), 3);	// Force md5 hash (does not contains special chars)
1396
-						$this->html = preg_replace("/src=\"$src\"|src='$src'/i", "src=\"cid:".$this->html_images[$i]["cid"]."\"", $this->html);
1397
-					}
1398
-					$i++;
1399
-				}
1400
-			}
1401
-
1402
-			if (!empty($this->html_images))
1403
-			{
1404
-				$inline = array();
1405
-
1406
-				$i=0;
1407
-
1408
-				foreach ($this->html_images as $img)
1409
-				{
1410
-					$fullpath = $images_dir.'/'.$img["name"];
1411
-
1412
-					// If duplicate images are embedded, they may show up as attachments, so remove them.
1413
-					if (!in_array($fullpath,$inline))
1414
-					{
1415
-						// Read image file
1416
-						if ($image = file_get_contents($fullpath))
1417
-						{
1418
-							// On garde que le nom de l'image
1419
-							preg_match('/([A-Za-z0-9_-]+[\.]?[A-Za-z0-9]+)?$/i',$img["name"],$regs);
1420
-							$imgName = $regs[1];
1421
-
1422
-							$this->images_encoded[$i]['name'] = $imgName;
1423
-							$this->images_encoded[$i]['fullpath'] = $fullpath;
1424
-							$this->images_encoded[$i]['content_type'] = $img["content_type"];
1425
-							$this->images_encoded[$i]['cid'] = $img["cid"];
1426
-							// Encodage de l'image
1427
-							$this->images_encoded[$i]["image_encoded"] = chunk_split(base64_encode($image), 68, $this->eol);
1428
-							$inline[] = $fullpath;
1429
-						}
1430
-					}
1431
-					$i++;
1432
-				}
1433
-			}
1434
-			else
1435
-			{
1436
-				return -1;
1437
-			}
1438
-
1439
-			return 1;
1440
-		}
1441
-		else
1442
-		{
1443
-			return 0;
1444
-		}
1445
-	}
1446
-
1447
-	/**
1448
-	 * Return a formatted address string for SMTP protocol
1449
-	 *
1450
-	 * @param	string		$address		     Example: 'John Doe <[email protected]>, Alan Smith <[email protected]>' or '[email protected], [email protected]'
1451
-	 * @param	int			$format			     0=auto, 1=emails with <>, 2=emails without <>, 3=auto + label between "
1452
-	 * @param	int			$encode			     0=No encode name, 1=Encode name to RFC2822
1453
-	 * @param   int         $maxnumberofemail    0=No limit. Otherwise, maximum number of emails returned ($address may contains several email separated with ','). Add '...' if there is more.
1454
-	 * @return	string						     If format 0: '<[email protected]>' or 'John Doe <[email protected]>' or '=?UTF-8?B?Sm9obiBEb2U=?= <[email protected]>'
1455
-	 * 										     If format 1: '<[email protected]>'
1456
-	 *										     If format 2: '[email protected]'
1457
-	 *										     If format 3: '<[email protected]>' or '"John Doe" <[email protected]>' or '"=?UTF-8?B?Sm9obiBEb2U=?=" <[email protected]>'
1458
-	 *                                           If format 4: 'John Doe' or '[email protected]' if no label exists
1459
-	 */
1460
-	static function getValidAddress($address,$format,$encode=0,$maxnumberofemail=0)
1461
-	{
1462
-		global $conf;
1463
-
1464
-		$ret='';
1465
-
1466
-		$arrayaddress=explode(',',$address);
1467
-
1468
-		// Boucle sur chaque composant de l'adresse
1469
-		$i=0;
1470
-		foreach($arrayaddress as $val)
1471
-		{
1472
-			if (preg_match('/^(.*)<(.*)>$/i',trim($val),$regs))
1473
-			{
1474
-				$name  = trim($regs[1]);
1475
-				$email = trim($regs[2]);
1476
-			}
1477
-			else
1478
-			{
1479
-				$name  = '';
1480
-				$email = trim($val);
1481
-			}
1482
-
1483
-			if ($email)
1484
-			{
1485
-				$i++;
1486
-
1487
-				$newemail='';
1488
-				if ($format == 4)
1489
-				{
1490
-					$newemail = $name?$name:$email;
1491
-				}
1492
-				if ($format == 2)
1493
-				{
1494
-					$newemail=$email;
1495
-				}
1496
-				if ($format == 1 || $format == 3)
1497
-				{
1498
-					$newemail='<'.$email.'>';
1499
-				}
1500
-				if ($format == 0 || $format == 3)
1501
-				{
1502
-					if (! empty($conf->global->MAIN_MAIL_NO_FULL_EMAIL)) $newemail='<'.$email.'>';
1503
-					elseif (! $name) $newemail='<'.$email.'>';
1504
-					else $newemail=($format==3?'"':'').($encode?self::encodetorfc2822($name):$name).($format==3?'"':'').' <'.$email.'>';
1505
-				}
1506
-
1507
-				$ret=($ret ? $ret.',' : '').$newemail;
1508
-
1509
-				// Stop if we have too much records
1510
-				if ($maxnumberofemail && $i >= $maxnumberofemail)
1511
-				{
1512
-					if (count($arrayaddress) > $maxnumberofemail) $ret.='...';
1513
-					break;
1514
-				}
1515
-			}
1516
-		}
1517
-
1518
-		return $ret;
1519
-	}
1520
-
1521
-	/**
1522
-	 * Return a formatted array of address string for SMTP protocol
1523
-	 *
1524
-	 * @param   string      $address        Example: 'John Doe <[email protected]>, Alan Smith <[email protected]>' or '[email protected], [email protected]'
1525
-	 * @return  array                       array of email => name
1526
-	 */
1527
-	function getArrayAddress($address)
1528
-	{
1529
-		global $conf;
1530
-
1531
-		$ret=array();
1532
-
1533
-		$arrayaddress=explode(',',$address);
1534
-
1535
-		// Boucle sur chaque composant de l'adresse
1536
-		foreach($arrayaddress as $val)
1537
-		{
1538
-			if (preg_match('/^(.*)<(.*)>$/i',trim($val),$regs))
1539
-			{
1540
-				$name  = trim($regs[1]);
1541
-				$email = trim($regs[2]);
1542
-			}
1543
-			else
1544
-			{
1545
-				$name  = null;
1546
-				$email = trim($val);
1547
-			}
1548
-
1549
-			$ret[$email]=empty($conf->global->MAIN_MAIL_NO_FULL_EMAIL)?$name:null;
1550
-		}
1551
-
1552
-		return $ret;
1553
-	}
1331
+        $_retVal = true;	// Indicates if Object was created or not
1332
+        $server_response = '';
1333
+
1334
+        while (substr($server_response,3,1) != ' ')
1335
+        {
1336
+            if (! ($server_response = fgets($socket, 256)) )
1337
+            {
1338
+                $this->error="Couldn't get mail server response codes";
1339
+                return false;
1340
+            }
1341
+        }
1342
+
1343
+        if( !( substr($server_response, 0, 3) == $response ) )
1344
+        {
1345
+            $this->error="Ran into problems sending Mail.\r\nResponse: $server_response";
1346
+            $_retVal = false;
1347
+        }
1348
+
1349
+        return $_retVal;
1350
+    }
1351
+
1352
+    /**
1353
+     * Seearch images into html message and init array this->images_encoded if found
1354
+     *
1355
+     * @param	string	$images_dir		Location of physical images files
1356
+     * @return	int 		        	>0 if OK, <0 if KO
1357
+     */
1358
+    function findHtmlImages($images_dir)
1359
+    {
1360
+        // Build the list of image extensions
1361
+        $extensions = array_keys($this->image_types);
1362
+
1363
+        $matches = array();
1364
+        preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches);  // If "xxx.ext" or 'xxx.ext' found
1365
+
1366
+        if (! empty($matches))
1367
+        {
1368
+            $i=0;
1369
+            foreach ($matches[1] as $full)
1370
+            {
1371
+
1372
+                if (preg_match('/file=([A-Za-z0-9_\-\/]+[\.]?[A-Za-z0-9]+)?$/i',$full,$regs))   // If xxx is 'file=aaa'
1373
+                {
1374
+                    $img = $regs[1];
1375
+
1376
+                    if (file_exists($images_dir.'/'.$img))
1377
+                    {
1378
+                        // Image path in src
1379
+                        $src = preg_quote($full,'/');
1380
+
1381
+                        // Image full path
1382
+                        $this->html_images[$i]["fullpath"] = $images_dir.'/'.$img;
1383
+
1384
+                        // Image name
1385
+                        $this->html_images[$i]["name"] = $img;
1386
+
1387
+                        // Content type
1388
+                        if (preg_match('/^.+\.(\w{3,4})$/', $img, $reg))
1389
+                        {
1390
+                            $ext=strtolower($reg[1]);
1391
+                            $this->html_images[$i]["content_type"] = $this->image_types[$ext];
1392
+                        }
1393
+
1394
+                        // cid
1395
+                        $this->html_images[$i]["cid"] = dol_hash(uniqid(time()), 3);	// Force md5 hash (does not contains special chars)
1396
+                        $this->html = preg_replace("/src=\"$src\"|src='$src'/i", "src=\"cid:".$this->html_images[$i]["cid"]."\"", $this->html);
1397
+                    }
1398
+                    $i++;
1399
+                }
1400
+            }
1401
+
1402
+            if (!empty($this->html_images))
1403
+            {
1404
+                $inline = array();
1405
+
1406
+                $i=0;
1407
+
1408
+                foreach ($this->html_images as $img)
1409
+                {
1410
+                    $fullpath = $images_dir.'/'.$img["name"];
1411
+
1412
+                    // If duplicate images are embedded, they may show up as attachments, so remove them.
1413
+                    if (!in_array($fullpath,$inline))
1414
+                    {
1415
+                        // Read image file
1416
+                        if ($image = file_get_contents($fullpath))
1417
+                        {
1418
+                            // On garde que le nom de l'image
1419
+                            preg_match('/([A-Za-z0-9_-]+[\.]?[A-Za-z0-9]+)?$/i',$img["name"],$regs);
1420
+                            $imgName = $regs[1];
1421
+
1422
+                            $this->images_encoded[$i]['name'] = $imgName;
1423
+                            $this->images_encoded[$i]['fullpath'] = $fullpath;
1424
+                            $this->images_encoded[$i]['content_type'] = $img["content_type"];
1425
+                            $this->images_encoded[$i]['cid'] = $img["cid"];
1426
+                            // Encodage de l'image
1427
+                            $this->images_encoded[$i]["image_encoded"] = chunk_split(base64_encode($image), 68, $this->eol);
1428
+                            $inline[] = $fullpath;
1429
+                        }
1430
+                    }
1431
+                    $i++;
1432
+                }
1433
+            }
1434
+            else
1435
+            {
1436
+                return -1;
1437
+            }
1438
+
1439
+            return 1;
1440
+        }
1441
+        else
1442
+        {
1443
+            return 0;
1444
+        }
1445
+    }
1446
+
1447
+    /**
1448
+     * Return a formatted address string for SMTP protocol
1449
+     *
1450
+     * @param	string		$address		     Example: 'John Doe <[email protected]>, Alan Smith <[email protected]>' or '[email protected], [email protected]'
1451
+     * @param	int			$format			     0=auto, 1=emails with <>, 2=emails without <>, 3=auto + label between "
1452
+     * @param	int			$encode			     0=No encode name, 1=Encode name to RFC2822
1453
+     * @param   int         $maxnumberofemail    0=No limit. Otherwise, maximum number of emails returned ($address may contains several email separated with ','). Add '...' if there is more.
1454
+     * @return	string						     If format 0: '<[email protected]>' or 'John Doe <[email protected]>' or '=?UTF-8?B?Sm9obiBEb2U=?= <[email protected]>'
1455
+     * 										     If format 1: '<[email protected]>'
1456
+     *										     If format 2: '[email protected]'
1457
+     *										     If format 3: '<[email protected]>' or '"John Doe" <[email protected]>' or '"=?UTF-8?B?Sm9obiBEb2U=?=" <[email protected]>'
1458
+     *                                           If format 4: 'John Doe' or '[email protected]' if no label exists
1459
+     */
1460
+    static function getValidAddress($address,$format,$encode=0,$maxnumberofemail=0)
1461
+    {
1462
+        global $conf;
1463
+
1464
+        $ret='';
1465
+
1466
+        $arrayaddress=explode(',',$address);
1467
+
1468
+        // Boucle sur chaque composant de l'adresse
1469
+        $i=0;
1470
+        foreach($arrayaddress as $val)
1471
+        {
1472
+            if (preg_match('/^(.*)<(.*)>$/i',trim($val),$regs))
1473
+            {
1474
+                $name  = trim($regs[1]);
1475
+                $email = trim($regs[2]);
1476
+            }
1477
+            else
1478
+            {
1479
+                $name  = '';
1480
+                $email = trim($val);
1481
+            }
1482
+
1483
+            if ($email)
1484
+            {
1485
+                $i++;
1486
+
1487
+                $newemail='';
1488
+                if ($format == 4)
1489
+                {
1490
+                    $newemail = $name?$name:$email;
1491
+                }
1492
+                if ($format == 2)
1493
+                {
1494
+                    $newemail=$email;
1495
+                }
1496
+                if ($format == 1 || $format == 3)
1497
+                {
1498
+                    $newemail='<'.$email.'>';
1499
+                }
1500
+                if ($format == 0 || $format == 3)
1501
+                {
1502
+                    if (! empty($conf->global->MAIN_MAIL_NO_FULL_EMAIL)) $newemail='<'.$email.'>';
1503
+                    elseif (! $name) $newemail='<'.$email.'>';
1504
+                    else $newemail=($format==3?'"':'').($encode?self::encodetorfc2822($name):$name).($format==3?'"':'').' <'.$email.'>';
1505
+                }
1506
+
1507
+                $ret=($ret ? $ret.',' : '').$newemail;
1508
+
1509
+                // Stop if we have too much records
1510
+                if ($maxnumberofemail && $i >= $maxnumberofemail)
1511
+                {
1512
+                    if (count($arrayaddress) > $maxnumberofemail) $ret.='...';
1513
+                    break;
1514
+                }
1515
+            }
1516
+        }
1517
+
1518
+        return $ret;
1519
+    }
1520
+
1521
+    /**
1522
+     * Return a formatted array of address string for SMTP protocol
1523
+     *
1524
+     * @param   string      $address        Example: 'John Doe <[email protected]>, Alan Smith <[email protected]>' or '[email protected], [email protected]'
1525
+     * @return  array                       array of email => name
1526
+     */
1527
+    function getArrayAddress($address)
1528
+    {
1529
+        global $conf;
1530
+
1531
+        $ret=array();
1532
+
1533
+        $arrayaddress=explode(',',$address);
1534
+
1535
+        // Boucle sur chaque composant de l'adresse
1536
+        foreach($arrayaddress as $val)
1537
+        {
1538
+            if (preg_match('/^(.*)<(.*)>$/i',trim($val),$regs))
1539
+            {
1540
+                $name  = trim($regs[1]);
1541
+                $email = trim($regs[2]);
1542
+            }
1543
+            else
1544
+            {
1545
+                $name  = null;
1546
+                $email = trim($val);
1547
+            }
1548
+
1549
+            $ret[$email]=empty($conf->global->MAIN_MAIL_NO_FULL_EMAIL)?$name:null;
1550
+        }
1551
+
1552
+        return $ret;
1553
+    }
1554 1554
 }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/CSMSFile.class.php 1 patch
Indentation   +162 added lines, -162 removed lines patch added patch discarded remove patch
@@ -35,73 +35,73 @@  discard block
 block discarded – undo
35 35
 class CSMSFile
36 36
 {
37 37
     /**
38
-	 * @var string Error code (or message)
39
-	 */
40
-	public $error='';
41
-
42
-	public $addr_from;
43
-	public $addr_to;
44
-	public $deferred;
45
-	public $priority;
46
-	public $class;
47
-	public $message;
48
-	public $nostop;
49
-
50
-
51
-	/**
52
-	 *	CSMSFile
53
-	 *
54
-	 *	@param	string	$to                 Recipients SMS
55
-	 *	@param 	string	$from               Sender SMS
56
-	 *	@param 	string	$msg                Message
57
-	 *	@param 	int		$deliveryreceipt	Not used
58
-	 *	@param 	int		$deferred			Deferred or not
59
-	 *	@param 	int		$priority			Priority
60
-	 *	@param 	int		$class				Class
61
-	 */
62
-	function __construct($to,$from,$msg,$deliveryreceipt=0,$deferred=0,$priority=3,$class=1)
63
-	{
64
-		global $conf;
65
-
66
-		// On definit fin de ligne
67
-		$this->eol="\n";
68
-		if (preg_match('/^win/i',PHP_OS)) $this->eol="\r\n";
69
-		if (preg_match('/^mac/i',PHP_OS)) $this->eol="\r";
70
-
71
-		// If ending method not defined
72
-		if (empty($conf->global->MAIN_SMS_SENDMODE))
73
-		{
74
-		    $this->error='No SMS Engine defined';
75
-		    return -1;
76
-		}
77
-
78
-		dol_syslog("CSMSFile::CSMSFile: MAIN_SMS_SENDMODE=".$conf->global->MAIN_SMS_SENDMODE." charset=".$conf->file->character_set_client." from=".$from.", to=".$to.", msg length=".count($msg), LOG_DEBUG);
79
-		dol_syslog("CSMSFile::CSMSFile: deferred=".$deferred." priority=".$priority." class=".$class, LOG_DEBUG);
80
-
81
-		// Action according to choosed sending method
82
-	    $this->addr_from=$from;
83
-	    $this->addr_to=$to;
38
+     * @var string Error code (or message)
39
+     */
40
+    public $error='';
41
+
42
+    public $addr_from;
43
+    public $addr_to;
44
+    public $deferred;
45
+    public $priority;
46
+    public $class;
47
+    public $message;
48
+    public $nostop;
49
+
50
+
51
+    /**
52
+     *	CSMSFile
53
+     *
54
+     *	@param	string	$to                 Recipients SMS
55
+     *	@param 	string	$from               Sender SMS
56
+     *	@param 	string	$msg                Message
57
+     *	@param 	int		$deliveryreceipt	Not used
58
+     *	@param 	int		$deferred			Deferred or not
59
+     *	@param 	int		$priority			Priority
60
+     *	@param 	int		$class				Class
61
+     */
62
+    function __construct($to,$from,$msg,$deliveryreceipt=0,$deferred=0,$priority=3,$class=1)
63
+    {
64
+        global $conf;
65
+
66
+        // On definit fin de ligne
67
+        $this->eol="\n";
68
+        if (preg_match('/^win/i',PHP_OS)) $this->eol="\r\n";
69
+        if (preg_match('/^mac/i',PHP_OS)) $this->eol="\r";
70
+
71
+        // If ending method not defined
72
+        if (empty($conf->global->MAIN_SMS_SENDMODE))
73
+        {
74
+            $this->error='No SMS Engine defined';
75
+            return -1;
76
+        }
77
+
78
+        dol_syslog("CSMSFile::CSMSFile: MAIN_SMS_SENDMODE=".$conf->global->MAIN_SMS_SENDMODE." charset=".$conf->file->character_set_client." from=".$from.", to=".$to.", msg length=".count($msg), LOG_DEBUG);
79
+        dol_syslog("CSMSFile::CSMSFile: deferred=".$deferred." priority=".$priority." class=".$class, LOG_DEBUG);
80
+
81
+        // Action according to choosed sending method
82
+        $this->addr_from=$from;
83
+        $this->addr_to=$to;
84 84
         $this->deferred=$deferred;
85 85
         $this->priority=$priority;
86 86
         $this->class=$class;
87 87
         $this->message=$msg;
88 88
         $this->nostop=false;
89
-	}
89
+    }
90 90
 
91 91
 
92
-	/**
93
-	 * Send sms that was prepared by constructor
94
-	 *
95
-	 * @return    boolean     True if sms sent, false otherwise
96
-	 */
97
-	function sendfile()
98
-	{
99
-		global $conf;
92
+    /**
93
+     * Send sms that was prepared by constructor
94
+     *
95
+     * @return    boolean     True if sms sent, false otherwise
96
+     */
97
+    function sendfile()
98
+    {
99
+        global $conf;
100 100
 
101
-		$errorlevel=error_reporting();
102
-		error_reporting($errorlevel ^ E_WARNING);   // Desactive warnings
101
+        $errorlevel=error_reporting();
102
+        error_reporting($errorlevel ^ E_WARNING);   // Desactive warnings
103 103
 
104
-		$res=false;
104
+        $res=false;
105 105
 
106 106
         dol_syslog("CSMSFile::sendfile addr_to=".$this->addr_to, LOG_DEBUG);
107 107
         dol_syslog("CSMSFile::sendfile message=\n".$this->message);
@@ -110,121 +110,121 @@  discard block
 block discarded – undo
110 110
 
111 111
         if (! empty($conf->global->MAIN_SMS_DEBUG)) $this->dump_sms();
112 112
 
113
-		if (empty($conf->global->MAIN_DISABLE_ALL_SMS))
114
-		{
115
-
116
-		    // Action according to choosed sending method
117
-		    if ($conf->global->MAIN_SMS_SENDMODE == 'ovh')    // Backward compatibility    @deprecated
118
-			{
119
-				dol_include_once('/ovh/class/ovhsms.class.php');
120
-				$sms=new OvhSms($this->db);
121
-				$sms->expe=$this->addr_from;
122
-				$sms->dest=$this->addr_to;
123
-				$sms->message=$this->message;
124
-				$sms->deferred=$this->deferred;
125
-				$sms->priority=$this->priority;
113
+        if (empty($conf->global->MAIN_DISABLE_ALL_SMS))
114
+        {
115
+
116
+            // Action according to choosed sending method
117
+            if ($conf->global->MAIN_SMS_SENDMODE == 'ovh')    // Backward compatibility    @deprecated
118
+            {
119
+                dol_include_once('/ovh/class/ovhsms.class.php');
120
+                $sms=new OvhSms($this->db);
121
+                $sms->expe=$this->addr_from;
122
+                $sms->dest=$this->addr_to;
123
+                $sms->message=$this->message;
124
+                $sms->deferred=$this->deferred;
125
+                $sms->priority=$this->priority;
126 126
                 $sms->class=$this->class;
127 127
                 $sms->nostop=$this->nostop;
128 128
 
129 129
                 $res=$sms->SmsSend();
130
-				if ($res <= 0)
131
-				{
132
-					$this->error=$sms->error;
133
-					dol_syslog("CSMSFile::sendfile: sms send error=".$this->error, LOG_ERR);
134
-				}
135
-				else
136
-				{
137
-					dol_syslog("CSMSFile::sendfile: sms send success with id=".$res, LOG_DEBUG);
138
-					//var_dump($res);        // 1973128
139
-					if (! empty($conf->global->MAIN_SMS_DEBUG)) $this->dump_sms_result($res);
140
-				}
141
-			}
142
-		    else if (! empty($conf->global->MAIN_SMS_SENDMODE))    // $conf->global->MAIN_SMS_SENDMODE looks like a value 'class@module'
143
-		    {
144
-		        $tmp=explode('@',$conf->global->MAIN_SMS_SENDMODE);
145
-		        $classfile=$tmp[0]; $module=(empty($tmp[1])?$tmp[0]:$tmp[1]);
146
-		        dol_include_once('/'.$module.'/class/'.$classfile.'.class.php');
147
-		        try
148
-		        {
149
-		            $classname=ucfirst($classfile);
150
-		            $sms = new $classname($this->db);
151
-		            $sms->expe=$this->addr_from;
152
-		            $sms->dest=$this->addr_to;
153
-		            $sms->deferred=$this->deferred;
154
-		            $sms->priority=$this->priority;
155
-		            $sms->class=$this->class;
156
-		            $sms->message=$this->message;
157
-		            $sms->nostop=$this->nostop;
130
+                if ($res <= 0)
131
+                {
132
+                    $this->error=$sms->error;
133
+                    dol_syslog("CSMSFile::sendfile: sms send error=".$this->error, LOG_ERR);
134
+                }
135
+                else
136
+                {
137
+                    dol_syslog("CSMSFile::sendfile: sms send success with id=".$res, LOG_DEBUG);
138
+                    //var_dump($res);        // 1973128
139
+                    if (! empty($conf->global->MAIN_SMS_DEBUG)) $this->dump_sms_result($res);
140
+                }
141
+            }
142
+            else if (! empty($conf->global->MAIN_SMS_SENDMODE))    // $conf->global->MAIN_SMS_SENDMODE looks like a value 'class@module'
143
+            {
144
+                $tmp=explode('@',$conf->global->MAIN_SMS_SENDMODE);
145
+                $classfile=$tmp[0]; $module=(empty($tmp[1])?$tmp[0]:$tmp[1]);
146
+                dol_include_once('/'.$module.'/class/'.$classfile.'.class.php');
147
+                try
148
+                {
149
+                    $classname=ucfirst($classfile);
150
+                    $sms = new $classname($this->db);
151
+                    $sms->expe=$this->addr_from;
152
+                    $sms->dest=$this->addr_to;
153
+                    $sms->deferred=$this->deferred;
154
+                    $sms->priority=$this->priority;
155
+                    $sms->class=$this->class;
156
+                    $sms->message=$this->message;
157
+                    $sms->nostop=$this->nostop;
158 158
 
159 159
                     $res=$sms->SmsSend();
160 160
                     $this->error = $sms->error;
161 161
                     $this->errors = $sms->errors;
162
-    				if ($res <= 0)
163
-    				{
164
-    					dol_syslog("CSMSFile::sendfile: sms send error=".$this->error, LOG_ERR);
165
-    				}
166
-    				else
167
-    				{
168
-    					dol_syslog("CSMSFile::sendfile: sms send success with id=".$res, LOG_DEBUG);
169
-    					//var_dump($res);        // 1973128
170
-    					if (! empty($conf->global->MAIN_SMS_DEBUG)) $this->dump_sms_result($res);
171
-    				}
172
-		        }
173
-		        catch(Exception $e)
174
-		        {
175
-		            dol_print_error('','Error to get list of senders: '.$e->getMessage());
176
-		        }
177
-		    }
178
-			else
179
-			{
180
-				// Send sms method not correctly defined
181
-				// --------------------------------------
182
-
183
-				return 'Bad value for MAIN_SMS_SENDMODE constant';
184
-			}
185
-		}
186
-		else
187
-		{
188
-			$this->error='No sms sent. Feature is disabled by option MAIN_DISABLE_ALL_SMS';
189
-			dol_syslog("CSMSFile::sendfile: ".$this->error, LOG_WARNING);
190
-		}
191
-
192
-		error_reporting($errorlevel);              // Reactive niveau erreur origine
193
-
194
-		return $res;
195
-	}
162
+                    if ($res <= 0)
163
+                    {
164
+                        dol_syslog("CSMSFile::sendfile: sms send error=".$this->error, LOG_ERR);
165
+                    }
166
+                    else
167
+                    {
168
+                        dol_syslog("CSMSFile::sendfile: sms send success with id=".$res, LOG_DEBUG);
169
+                        //var_dump($res);        // 1973128
170
+                        if (! empty($conf->global->MAIN_SMS_DEBUG)) $this->dump_sms_result($res);
171
+                    }
172
+                }
173
+                catch(Exception $e)
174
+                {
175
+                    dol_print_error('','Error to get list of senders: '.$e->getMessage());
176
+                }
177
+            }
178
+            else
179
+            {
180
+                // Send sms method not correctly defined
181
+                // --------------------------------------
182
+
183
+                return 'Bad value for MAIN_SMS_SENDMODE constant';
184
+            }
185
+        }
186
+        else
187
+        {
188
+            $this->error='No sms sent. Feature is disabled by option MAIN_DISABLE_ALL_SMS';
189
+            dol_syslog("CSMSFile::sendfile: ".$this->error, LOG_WARNING);
190
+        }
191
+
192
+        error_reporting($errorlevel);              // Reactive niveau erreur origine
193
+
194
+        return $res;
195
+    }
196 196
 
197 197
 
198 198
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
199
-	/**
200
-	 *  Write content of a SendSms request into a dump file (mode = all)
201
-	 *  Used for debugging.
202
-	 *
203
-	 *  @return	void
204
-	 */
205
-	function dump_sms()
206
-	{
199
+    /**
200
+     *  Write content of a SendSms request into a dump file (mode = all)
201
+     *  Used for debugging.
202
+     *
203
+     *  @return	void
204
+     */
205
+    function dump_sms()
206
+    {
207 207
         // phpcs:enable
208
-		global $conf,$dolibarr_main_data_root;
209
-
210
-		if (@is_writeable($dolibarr_main_data_root))	// Avoid fatal error on fopen with open_basedir
211
-		{
212
-			$outputfile=$dolibarr_main_data_root."/dolibarr_sms.log";
213
-			$fp = fopen($outputfile,"w");
214
-
215
-			fputs($fp, "From: ".$this->addr_from."\n");
216
-			fputs($fp, "To: ".$this->addr_to."\n");
217
-			fputs($fp, "Priority: ".$this->priority."\n");
218
-			fputs($fp, "Class: ".$this->class."\n");
219
-			fputs($fp, "Deferred: ".$this->deferred."\n");
220
-			fputs($fp, "DisableStop: ".$this->nostop."\n");
221
-			fputs($fp, "Message:\n".$this->message);
222
-
223
-			fclose($fp);
224
-			if (! empty($conf->global->MAIN_UMASK))
225
-			@chmod($outputfile, octdec($conf->global->MAIN_UMASK));
226
-		}
227
-	}
208
+        global $conf,$dolibarr_main_data_root;
209
+
210
+        if (@is_writeable($dolibarr_main_data_root))	// Avoid fatal error on fopen with open_basedir
211
+        {
212
+            $outputfile=$dolibarr_main_data_root."/dolibarr_sms.log";
213
+            $fp = fopen($outputfile,"w");
214
+
215
+            fputs($fp, "From: ".$this->addr_from."\n");
216
+            fputs($fp, "To: ".$this->addr_to."\n");
217
+            fputs($fp, "Priority: ".$this->priority."\n");
218
+            fputs($fp, "Class: ".$this->class."\n");
219
+            fputs($fp, "Deferred: ".$this->deferred."\n");
220
+            fputs($fp, "DisableStop: ".$this->nostop."\n");
221
+            fputs($fp, "Message:\n".$this->message);
222
+
223
+            fclose($fp);
224
+            if (! empty($conf->global->MAIN_UMASK))
225
+            @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
226
+        }
227
+    }
228 228
 
229 229
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
230 230
     /**
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
 
242 242
         if (@is_writeable($dolibarr_main_data_root))    // Avoid fatal error on fopen with open_basedir
243 243
         {
244
-        	$outputfile=$dolibarr_main_data_root."/dolibarr_sms.log";
244
+            $outputfile=$dolibarr_main_data_root."/dolibarr_sms.log";
245 245
             $fp = fopen($outputfile,"a+");
246 246
 
247 247
             fputs($fp, "\nResult id=".$result);
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/fileupload.class.php 1 patch
Indentation   +516 added lines, -516 removed lines patch added patch discarded remove patch
@@ -30,143 +30,143 @@  discard block
 block discarded – undo
30 30
  */
31 31
 class FileUpload
32 32
 {
33
-	protected $options;
34
-	protected $fk_element;
35
-	protected $element;
36
-
37
-	/**
38
-	 * Constructor
39
-	 *
40
-	 * @param array		$options		Options array
41
-	 * @param int		$fk_element		fk_element
42
-	 * @param string	$element		element
43
-	 */
44
-	function __construct($options=null,$fk_element=null,$element=null)
45
-	{
46
-		global $db, $conf;
47
-		global $object;
48
-
49
-		$this->fk_element=$fk_element;
50
-		$this->element=$element;
51
-
52
-		$pathname=$filename=$element;
53
-		if (preg_match('/^([^_]+)_([^_]+)/i',$element,$regs))
54
-		{
55
-			$pathname = $regs[1];
56
-			$filename = $regs[2];
57
-		}
58
-
59
-		$parentForeignKey = '';
60
-
61
-		// For compatibility
62
-		if ($element == 'propal') {
63
-			$pathname = 'comm/propal';
64
-			$dir_output=$conf->$element->dir_output;
65
-		}
66
-		elseif ($element == 'facture') {
67
-			$pathname = 'compta/facture';
68
-			$dir_output=$conf->$element->dir_output;
69
-		}
70
-		elseif ($element == 'project') {
71
-			$element = $pathname = 'projet';
72
-			$dir_output=$conf->$element->dir_output;
73
-		}
74
-		elseif ($element == 'project_task') {
75
-			$pathname = 'projet'; $filename='task';
76
-			$dir_output=$conf->projet->dir_output;
77
-			$parentForeignKey = 'fk_project';
78
-			$parentClass = 'Project';
79
-			$parentElement = 'projet';
80
-			$parentObject = 'project';
81
-		}
82
-		elseif ($element == 'fichinter') {
83
-			$element='ficheinter';
84
-			$dir_output=$conf->$element->dir_output;
85
-		}
86
-		elseif ($element == 'order_supplier') {
87
-			$pathname = 'fourn'; $filename='fournisseur.commande';
88
-			$dir_output=$conf->fournisseur->commande->dir_output;
89
-		}
90
-		elseif ($element == 'invoice_supplier') {
91
-			$pathname = 'fourn'; $filename='fournisseur.facture';
92
-			$dir_output=$conf->fournisseur->facture->dir_output;
93
-		}
94
-		elseif ($element == 'product') {
95
-			$dir_output = $conf->product->multidir_output[$conf->entity];
96
-		}
97
-		elseif ($element == 'productbatch') {
98
-			$dir_output = $conf->productbatch->multidir_output[$conf->entity];
99
-		}
100
-		elseif ($element == 'action') {
101
-			$pathname = 'comm/action'; $filename='actioncomm';
102
-			$dir_output=$conf->agenda->dir_output;
103
-		}
104
-		elseif ($element == 'chargesociales') {
105
-			$pathname = 'compta/sociales'; $filename='chargesociales';
106
-			$dir_output=$conf->tax->dir_output;
107
-		} else {
108
-			$dir_output=$conf->$element->dir_output;
109
-		}
110
-
111
-		dol_include_once('/'.$pathname.'/class/'.$filename.'.class.php');
112
-
113
-		$classname = ucfirst($filename);
114
-
115
-		if ($element == 'order_supplier') {
116
-			$classname = 'CommandeFournisseur';
117
-		} elseif ($element == 'invoice_supplier') {
118
-			$classname = 'FactureFournisseur';
119
-		}
120
-
121
-		$object = new $classname($db);
122
-
123
-		$object->fetch($fk_element);
124
-		if (!empty($parentForeignKey)) {
125
-			dol_include_once('/'.$parentElement.'/class/'.$parentObject.'.class.php');
126
-			$parent = new $parentClass($db);
127
-			$parent->fetch($object->$parentForeignKey);
128
-			if (!empty($parent->socid)) {
129
-				$parent->fetch_thirdparty();
130
-			}
131
-			$object->$parentObject = clone $parent;
132
-		} else {
133
-			$object->fetch_thirdparty();
134
-		}
135
-
136
-		$object_ref = dol_sanitizeFileName($object->ref);
137
-		if ($element == 'invoice_supplier') {
138
-			$object_ref = get_exdir($object->id,2,0,0,$object,'invoice_supplier') . $object_ref;
139
-		} else if ($element == 'project_task') {
140
-			$object_ref = $object->project->ref . '/' . $object_ref;
141
-		}
142
-
143
-		$this->options = array(
144
-				'script_url' => $_SERVER['PHP_SELF'],
145
-				'upload_dir' => $dir_output . '/' . $object_ref . '/',
146
-				'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/',
147
-				'param_name' => 'files',
148
-				// Set the following option to 'POST', if your server does not support
149
-				// DELETE requests. This is a parameter sent to the client:
150
-				'delete_type' => 'DELETE',
151
-				// The php.ini settings upload_max_filesize and post_max_size
152
-				// take precedence over the following max_file_size setting:
153
-				'max_file_size' => null,
154
-				'min_file_size' => 1,
155
-				'accept_file_types' => '/.+$/i',
156
-				// The maximum number of files for the upload directory:
157
-				'max_number_of_files' => null,
158
-				// Image resolution restrictions:
159
-				'max_width' => null,
160
-				'max_height' => null,
161
-				'min_width' => 1,
162
-				'min_height' => 1,
163
-				// Set the following option to false to enable resumable uploads:
164
-				'discard_aborted_uploads' => true,
165
-				'image_versions' => array(
166
-						// Uncomment the following version to restrict the size of
167
-						// uploaded images. You can also add additional versions with
168
-						// their own upload directories:
169
-						/*
33
+    protected $options;
34
+    protected $fk_element;
35
+    protected $element;
36
+
37
+    /**
38
+     * Constructor
39
+     *
40
+     * @param array		$options		Options array
41
+     * @param int		$fk_element		fk_element
42
+     * @param string	$element		element
43
+     */
44
+    function __construct($options=null,$fk_element=null,$element=null)
45
+    {
46
+        global $db, $conf;
47
+        global $object;
48
+
49
+        $this->fk_element=$fk_element;
50
+        $this->element=$element;
51
+
52
+        $pathname=$filename=$element;
53
+        if (preg_match('/^([^_]+)_([^_]+)/i',$element,$regs))
54
+        {
55
+            $pathname = $regs[1];
56
+            $filename = $regs[2];
57
+        }
58
+
59
+        $parentForeignKey = '';
60
+
61
+        // For compatibility
62
+        if ($element == 'propal') {
63
+            $pathname = 'comm/propal';
64
+            $dir_output=$conf->$element->dir_output;
65
+        }
66
+        elseif ($element == 'facture') {
67
+            $pathname = 'compta/facture';
68
+            $dir_output=$conf->$element->dir_output;
69
+        }
70
+        elseif ($element == 'project') {
71
+            $element = $pathname = 'projet';
72
+            $dir_output=$conf->$element->dir_output;
73
+        }
74
+        elseif ($element == 'project_task') {
75
+            $pathname = 'projet'; $filename='task';
76
+            $dir_output=$conf->projet->dir_output;
77
+            $parentForeignKey = 'fk_project';
78
+            $parentClass = 'Project';
79
+            $parentElement = 'projet';
80
+            $parentObject = 'project';
81
+        }
82
+        elseif ($element == 'fichinter') {
83
+            $element='ficheinter';
84
+            $dir_output=$conf->$element->dir_output;
85
+        }
86
+        elseif ($element == 'order_supplier') {
87
+            $pathname = 'fourn'; $filename='fournisseur.commande';
88
+            $dir_output=$conf->fournisseur->commande->dir_output;
89
+        }
90
+        elseif ($element == 'invoice_supplier') {
91
+            $pathname = 'fourn'; $filename='fournisseur.facture';
92
+            $dir_output=$conf->fournisseur->facture->dir_output;
93
+        }
94
+        elseif ($element == 'product') {
95
+            $dir_output = $conf->product->multidir_output[$conf->entity];
96
+        }
97
+        elseif ($element == 'productbatch') {
98
+            $dir_output = $conf->productbatch->multidir_output[$conf->entity];
99
+        }
100
+        elseif ($element == 'action') {
101
+            $pathname = 'comm/action'; $filename='actioncomm';
102
+            $dir_output=$conf->agenda->dir_output;
103
+        }
104
+        elseif ($element == 'chargesociales') {
105
+            $pathname = 'compta/sociales'; $filename='chargesociales';
106
+            $dir_output=$conf->tax->dir_output;
107
+        } else {
108
+            $dir_output=$conf->$element->dir_output;
109
+        }
110
+
111
+        dol_include_once('/'.$pathname.'/class/'.$filename.'.class.php');
112
+
113
+        $classname = ucfirst($filename);
114
+
115
+        if ($element == 'order_supplier') {
116
+            $classname = 'CommandeFournisseur';
117
+        } elseif ($element == 'invoice_supplier') {
118
+            $classname = 'FactureFournisseur';
119
+        }
120
+
121
+        $object = new $classname($db);
122
+
123
+        $object->fetch($fk_element);
124
+        if (!empty($parentForeignKey)) {
125
+            dol_include_once('/'.$parentElement.'/class/'.$parentObject.'.class.php');
126
+            $parent = new $parentClass($db);
127
+            $parent->fetch($object->$parentForeignKey);
128
+            if (!empty($parent->socid)) {
129
+                $parent->fetch_thirdparty();
130
+            }
131
+            $object->$parentObject = clone $parent;
132
+        } else {
133
+            $object->fetch_thirdparty();
134
+        }
135
+
136
+        $object_ref = dol_sanitizeFileName($object->ref);
137
+        if ($element == 'invoice_supplier') {
138
+            $object_ref = get_exdir($object->id,2,0,0,$object,'invoice_supplier') . $object_ref;
139
+        } else if ($element == 'project_task') {
140
+            $object_ref = $object->project->ref . '/' . $object_ref;
141
+        }
142
+
143
+        $this->options = array(
144
+                'script_url' => $_SERVER['PHP_SELF'],
145
+                'upload_dir' => $dir_output . '/' . $object_ref . '/',
146
+                'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/',
147
+                'param_name' => 'files',
148
+                // Set the following option to 'POST', if your server does not support
149
+                // DELETE requests. This is a parameter sent to the client:
150
+                'delete_type' => 'DELETE',
151
+                // The php.ini settings upload_max_filesize and post_max_size
152
+                // take precedence over the following max_file_size setting:
153
+                'max_file_size' => null,
154
+                'min_file_size' => 1,
155
+                'accept_file_types' => '/.+$/i',
156
+                // The maximum number of files for the upload directory:
157
+                'max_number_of_files' => null,
158
+                // Image resolution restrictions:
159
+                'max_width' => null,
160
+                'max_height' => null,
161
+                'min_width' => 1,
162
+                'min_height' => 1,
163
+                // Set the following option to false to enable resumable uploads:
164
+                'discard_aborted_uploads' => true,
165
+                'image_versions' => array(
166
+                        // Uncomment the following version to restrict the size of
167
+                        // uploaded images. You can also add additional versions with
168
+                        // their own upload directories:
169
+                        /*
170 170
 		'large' => array(
171 171
 				'upload_dir' => dirname($_SERVER['SCRIPT_FILENAME']).'/files/',
172 172
 				'upload_url' => $this->getFullUrl().'/files/',
@@ -175,338 +175,338 @@  discard block
 block discarded – undo
175 175
 				'jpeg_quality' => 95
176 176
 		),
177 177
 		*/
178
-						'thumbnail' => array(
179
-								'upload_dir' => $dir_output . '/' . $object_ref . '/thumbs/',
180
-								'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/thumbs/',
181
-								'max_width' => 80,
182
-								'max_height' => 80
183
-						)
184
-				)
185
-		);
186
-		if ($options) {
187
-			$this->options = array_replace_recursive($this->options, $options);
188
-		}
189
-	}
190
-
191
-	/**
192
-	 *	Return full URL
193
-	 *
194
-	 *	@return	string			URL
195
-	 */
196
-	protected function getFullUrl()
197
-	{
198
-		$https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
199
-		return
200
-		($https ? 'https://' : 'http://').
201
-		(!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
202
-		(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
203
-				($https && $_SERVER['SERVER_PORT'] === 443 ||
204
-						$_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
205
-						substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
206
-	}
207
-
208
-	/**
209
-	 * Set delete url
210
-	 *
211
-	 * @param 	string	$file		Filename
212
-	 * @return	void
213
-	 */
214
-	protected function setFileDeleteUrl($file)
215
-	{
216
-		$file->delete_url = $this->options['script_url']
217
-		.'?file='.rawurlencode($file->name).'&fk_element='.$this->fk_element.'&element='.$this->element;
218
-		$file->delete_type = $this->options['delete_type'];
219
-		if ($file->delete_type !== 'DELETE') {
220
-			$file->delete_url .= '&_method=DELETE';
221
-		}
222
-	}
223
-
224
-	/**
225
-	 * getFileObject
226
-	 *
227
-	 * @param	string		$file_name		Filename
228
-	 * @return 	stdClass|null
229
-	 */
230
-	protected function getFileObject($file_name)
231
-	{
232
-		$file_path = $this->options['upload_dir'].$file_name;
233
-		if (is_file($file_path) && $file_name[0] !== '.')
234
-		{
235
-			$file = new stdClass();
236
-			$file->name = $file_name;
237
-			$file->mime = dol_mimetype($file_name,'',2);
238
-			$file->size = filesize($file_path);
239
-			$file->url = $this->options['upload_url'].rawurlencode($file->name);
240
-			foreach($this->options['image_versions'] as $version => $options) {
241
-				if (is_file($options['upload_dir'].$file_name)) {
242
-					$tmp=explode('.',$file->name);
243
-					$file->{$version.'_url'} = $options['upload_url'].rawurlencode($tmp[0].'_mini.'.$tmp[1]);
244
-				}
245
-			}
246
-			$this->setFileDeleteUrl($file);
247
-			return $file;
248
-		}
249
-		return null;
250
-	}
251
-
252
-	/**
253
-	 * getFileObjects
254
-	 *
255
-	 * @return	void
256
-	 */
257
-	protected function getFileObjects()
258
-	{
259
-		return array_values(array_filter(array_map(array($this, 'getFileObject'), scandir($this->options['upload_dir']))));
260
-	}
261
-
262
-	/**
263
-	 *  Create thumbs of a file uploaded. Only the "mini" thumb is generated.
264
-	 *
265
-	 *  @param	string	$file_name		Filename
266
-	 *  @param	string	$options 		is array('max_width', 'max_height')
267
-	 *  @return	boolean
268
-	 */
269
-	protected function createScaledImage($file_name, $options)
270
-	{
271
-		global $maxwidthmini, $maxheightmini;
272
-
273
-		$file_path = $this->options['upload_dir'].$file_name;
274
-		$new_file_path = $options['upload_dir'].$file_name;
275
-
276
-		if (dol_mkdir($options['upload_dir']) >= 0)
277
-		{
278
-			list($img_width, $img_height) = @getimagesize($file_path);
279
-			if (!$img_width || !$img_height) {
280
-				return false;
281
-			}
282
-
283
-			$res=vignette($file_path,$maxwidthmini,$maxheightmini,'_mini');  // We don't use ->addThumbs here because there is no object and we don't need all thumbs, only the "mini".
284
-
285
-			if (preg_match('/error/i',$res)) return false;
286
-			return true;
287
-		}
288
-		else
289
-		{
290
-			return false;
291
-		}
292
-	}
293
-
294
-	/**
295
-	 * Enter description here ...
296
-	 *
297
-	 * @param 	string	$uploaded_file		Uploade file
298
-	 * @param 	string	$file				File
299
-	 * @param 	string	$error				Error
300
-	 * @param	string	$index				Index
301
-	 * @return  boolean                     True if OK, False if KO
302
-	 */
303
-	protected function validate($uploaded_file, $file, $error, $index)
304
-	{
305
-		if ($error) {
306
-			$file->error = $error;
307
-			return false;
308
-		}
309
-		if (!$file->name) {
310
-			$file->error = 'missingFileName';
311
-			return false;
312
-		}
313
-		if (!preg_match($this->options['accept_file_types'], $file->name)) {
314
-			$file->error = 'acceptFileTypes';
315
-			return false;
316
-		}
317
-		if ($uploaded_file && is_uploaded_file($uploaded_file)) {
318
-			$file_size = filesize($uploaded_file);
319
-		} else {
320
-			$file_size = $_SERVER['CONTENT_LENGTH'];
321
-		}
322
-		if ($this->options['max_file_size'] && (
323
-				$file_size > $this->options['max_file_size'] ||
324
-				$file->size > $this->options['max_file_size'])
325
-		) {
326
-			$file->error = 'maxFileSize';
327
-			return false;
328
-		}
329
-		if ($this->options['min_file_size'] &&
330
-				$file_size < $this->options['min_file_size']) {
331
-			$file->error = 'minFileSize';
332
-			return false;
333
-		}
334
-		if (is_numeric($this->options['max_number_of_files']) && (
335
-				count($this->getFileObjects()) >= $this->options['max_number_of_files'])
336
-		) {
337
-			$file->error = 'maxNumberOfFiles';
338
-			return false;
339
-		}
340
-		list($img_width, $img_height) = @getimagesize($uploaded_file);
341
-		if (is_numeric($img_width)) {
342
-			if ($this->options['max_width'] && $img_width > $this->options['max_width'] ||
343
-					$this->options['max_height'] && $img_height > $this->options['max_height']) {
344
-				$file->error = 'maxResolution';
345
-				return false;
346
-			}
347
-			if ($this->options['min_width'] && $img_width < $this->options['min_width'] ||
348
-					$this->options['min_height'] && $img_height < $this->options['min_height']) {
349
-				$file->error = 'minResolution';
350
-				return false;
351
-			}
352
-		}
353
-		return true;
354
-	}
355
-
356
-	/**
357
-	 * Enter description here ...
358
-	 *
359
-	 * @param 	int		$matches		???
360
-	 * @return	string					???
361
-	 */
362
-	protected function upcountNameCallback($matches)
363
-	{
364
-		$index = isset($matches[1]) ? intval($matches[1]) + 1 : 1;
365
-		$ext = isset($matches[2]) ? $matches[2] : '';
366
-		return ' ('.$index.')'.$ext;
367
-	}
368
-
369
-	/**
370
-	 * Enter description here ...
371
-	 *
372
-	 * @param 	string		$name		???
373
-	 * @return	string					???
374
-	 */
375
-	protected function upcountName($name)
376
-	{
377
-		return preg_replace_callback('/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/', array($this, 'upcountNameCallback'), $name, 1);
378
-	}
379
-
380
-	/**
381
-	 * trimFileName
382
-	 *
383
-	 * @param 	string $name		Filename
384
-	 * @param 	string $type		???
385
-	 * @param 	string $index		???
386
-	 * @return	string
387
-	 */
388
-	protected function trimFileName($name, $type, $index)
389
-	{
390
-		// Remove path information and dots around the filename, to prevent uploading
391
-		// into different directories or replacing hidden system files.
392
-		// Also remove control characters and spaces (\x00..\x20) around the filename:
393
-		$file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
394
-		// Add missing file extension for known image types:
395
-		if (strpos($file_name, '.') === false &&
396
-				preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
397
-			$file_name .= '.'.$matches[1];
398
-		}
399
-		if ($this->options['discard_aborted_uploads'])
400
-		{
401
-			while(is_file($this->options['upload_dir'].$file_name))
402
-			{
403
-				$file_name = $this->upcountName($file_name);
404
-			}
405
-		}
406
-		return $file_name;
407
-	}
408
-
409
-	/**
410
-	 * handleFileUpload
411
-	 *
412
-	 * @param 	string		$uploaded_file		Uploade file
413
-	 * @param 	string		$name				Name
414
-	 * @param 	int			$size				Size
415
-	 * @param 	string		$type				Type
416
-	 * @param 	string		$error				Error
417
-	 * @param	string		$index				Index
418
-	 * @return stdClass
419
-	 */
420
-	protected function handleFileUpload($uploaded_file, $name, $size, $type, $error, $index)
421
-	{
422
-		$file = new stdClass();
423
-		$file->name = $this->trimFileName($name, $type, $index);
424
-		$file->mime = dol_mimetype($file->name,'',2);
425
-		$file->size = intval($size);
426
-		$file->type = $type;
427
-		if ($this->validate($uploaded_file, $file, $error, $index) && dol_mkdir($this->options['upload_dir']) >= 0)
428
-		{
429
-			$file_path = $this->options['upload_dir'].$file->name;
430
-			$append_file = !$this->options['discard_aborted_uploads'] && is_file($file_path) && $file->size > filesize($file_path);
431
-			clearstatcache();
432
-			if ($uploaded_file && is_uploaded_file($uploaded_file)) {
433
-				// multipart/formdata uploads (POST method uploads)
434
-				if ($append_file)
435
-				{
436
-					file_put_contents($file_path, fopen($uploaded_file, 'r'), FILE_APPEND);
437
-				} else {
438
-					dol_move_uploaded_file($uploaded_file, $file_path, 1, 0, 0, 0, 'userfile');
439
-				}
440
-			}
441
-			else
442
-			{
443
-				// Non-multipart uploads (PUT method support)
444
-				file_put_contents($file_path, fopen('php://input', 'r'), $append_file ? FILE_APPEND : 0);
445
-			}
446
-			$file_size = filesize($file_path);
447
-			if ($file_size === $file->size)
448
-			{
449
-				$file->url = $this->options['upload_url'].rawurlencode($file->name);
450
-				foreach($this->options['image_versions'] as $version => $options)
451
-				{
452
-					if ($this->createScaledImage($file->name, $options))
453
-					{
454
-						$tmp=explode('.',$file->name);
455
-						$file->{$version.'_url'} = $options['upload_url'].rawurlencode($tmp[0].'_mini.'.$tmp[1]);
456
-					}
457
-				}
458
-			}
459
-			else if ($this->options['discard_aborted_uploads'])
460
-			{
461
-				unlink($file_path);
462
-				$file->error = 'abort';
463
-			}
464
-			$file->size = $file_size;
465
-			$this->setFileDeleteUrl($file);
466
-		}
467
-		return $file;
468
-	}
469
-
470
-	/**
471
-	 * Output data
472
-	 *
473
-	 * @return	void
474
-	 */
475
-	public function get()
476
-	{
477
-		$file_name = isset($_REQUEST['file']) ?
478
-		basename(stripslashes($_REQUEST['file'])) : null;
479
-		if ($file_name)
480
-		{
481
-			$info = $this->getFileObject($file_name);
482
-		}
483
-		else
484
-		{
485
-			$info = $this->getFileObjects();
486
-		}
487
-		header('Content-type: application/json');
488
-		echo json_encode($info);
489
-	}
490
-
491
-	/**
492
-	 * Output data
493
-	 *
494
-	 * @return	void
495
-	 */
496
-	public function post()
497
-	{
498
-		if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE')
499
-		{
500
-			return $this->delete();
501
-		}
502
-		$upload = isset($_FILES[$this->options['param_name']]) ?
503
-		$_FILES[$this->options['param_name']] : null;
504
-		$info = array();
505
-		if ($upload && is_array($upload['tmp_name']))
506
-		{
507
-			// param_name is an array identifier like "files[]",
508
-			// $_FILES is a multi-dimensional array:
509
-			foreach ($upload['tmp_name'] as $index => $value) {
178
+                        'thumbnail' => array(
179
+                                'upload_dir' => $dir_output . '/' . $object_ref . '/thumbs/',
180
+                                'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.$element.'&attachment=1&file=/'.$object_ref.'/thumbs/',
181
+                                'max_width' => 80,
182
+                                'max_height' => 80
183
+                        )
184
+                )
185
+        );
186
+        if ($options) {
187
+            $this->options = array_replace_recursive($this->options, $options);
188
+        }
189
+    }
190
+
191
+    /**
192
+     *	Return full URL
193
+     *
194
+     *	@return	string			URL
195
+     */
196
+    protected function getFullUrl()
197
+    {
198
+        $https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
199
+        return
200
+        ($https ? 'https://' : 'http://').
201
+        (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
202
+        (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
203
+                ($https && $_SERVER['SERVER_PORT'] === 443 ||
204
+                        $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
205
+                        substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
206
+    }
207
+
208
+    /**
209
+     * Set delete url
210
+     *
211
+     * @param 	string	$file		Filename
212
+     * @return	void
213
+     */
214
+    protected function setFileDeleteUrl($file)
215
+    {
216
+        $file->delete_url = $this->options['script_url']
217
+        .'?file='.rawurlencode($file->name).'&fk_element='.$this->fk_element.'&element='.$this->element;
218
+        $file->delete_type = $this->options['delete_type'];
219
+        if ($file->delete_type !== 'DELETE') {
220
+            $file->delete_url .= '&_method=DELETE';
221
+        }
222
+    }
223
+
224
+    /**
225
+     * getFileObject
226
+     *
227
+     * @param	string		$file_name		Filename
228
+     * @return 	stdClass|null
229
+     */
230
+    protected function getFileObject($file_name)
231
+    {
232
+        $file_path = $this->options['upload_dir'].$file_name;
233
+        if (is_file($file_path) && $file_name[0] !== '.')
234
+        {
235
+            $file = new stdClass();
236
+            $file->name = $file_name;
237
+            $file->mime = dol_mimetype($file_name,'',2);
238
+            $file->size = filesize($file_path);
239
+            $file->url = $this->options['upload_url'].rawurlencode($file->name);
240
+            foreach($this->options['image_versions'] as $version => $options) {
241
+                if (is_file($options['upload_dir'].$file_name)) {
242
+                    $tmp=explode('.',$file->name);
243
+                    $file->{$version.'_url'} = $options['upload_url'].rawurlencode($tmp[0].'_mini.'.$tmp[1]);
244
+                }
245
+            }
246
+            $this->setFileDeleteUrl($file);
247
+            return $file;
248
+        }
249
+        return null;
250
+    }
251
+
252
+    /**
253
+     * getFileObjects
254
+     *
255
+     * @return	void
256
+     */
257
+    protected function getFileObjects()
258
+    {
259
+        return array_values(array_filter(array_map(array($this, 'getFileObject'), scandir($this->options['upload_dir']))));
260
+    }
261
+
262
+    /**
263
+     *  Create thumbs of a file uploaded. Only the "mini" thumb is generated.
264
+     *
265
+     *  @param	string	$file_name		Filename
266
+     *  @param	string	$options 		is array('max_width', 'max_height')
267
+     *  @return	boolean
268
+     */
269
+    protected function createScaledImage($file_name, $options)
270
+    {
271
+        global $maxwidthmini, $maxheightmini;
272
+
273
+        $file_path = $this->options['upload_dir'].$file_name;
274
+        $new_file_path = $options['upload_dir'].$file_name;
275
+
276
+        if (dol_mkdir($options['upload_dir']) >= 0)
277
+        {
278
+            list($img_width, $img_height) = @getimagesize($file_path);
279
+            if (!$img_width || !$img_height) {
280
+                return false;
281
+            }
282
+
283
+            $res=vignette($file_path,$maxwidthmini,$maxheightmini,'_mini');  // We don't use ->addThumbs here because there is no object and we don't need all thumbs, only the "mini".
284
+
285
+            if (preg_match('/error/i',$res)) return false;
286
+            return true;
287
+        }
288
+        else
289
+        {
290
+            return false;
291
+        }
292
+    }
293
+
294
+    /**
295
+     * Enter description here ...
296
+     *
297
+     * @param 	string	$uploaded_file		Uploade file
298
+     * @param 	string	$file				File
299
+     * @param 	string	$error				Error
300
+     * @param	string	$index				Index
301
+     * @return  boolean                     True if OK, False if KO
302
+     */
303
+    protected function validate($uploaded_file, $file, $error, $index)
304
+    {
305
+        if ($error) {
306
+            $file->error = $error;
307
+            return false;
308
+        }
309
+        if (!$file->name) {
310
+            $file->error = 'missingFileName';
311
+            return false;
312
+        }
313
+        if (!preg_match($this->options['accept_file_types'], $file->name)) {
314
+            $file->error = 'acceptFileTypes';
315
+            return false;
316
+        }
317
+        if ($uploaded_file && is_uploaded_file($uploaded_file)) {
318
+            $file_size = filesize($uploaded_file);
319
+        } else {
320
+            $file_size = $_SERVER['CONTENT_LENGTH'];
321
+        }
322
+        if ($this->options['max_file_size'] && (
323
+                $file_size > $this->options['max_file_size'] ||
324
+                $file->size > $this->options['max_file_size'])
325
+        ) {
326
+            $file->error = 'maxFileSize';
327
+            return false;
328
+        }
329
+        if ($this->options['min_file_size'] &&
330
+                $file_size < $this->options['min_file_size']) {
331
+            $file->error = 'minFileSize';
332
+            return false;
333
+        }
334
+        if (is_numeric($this->options['max_number_of_files']) && (
335
+                count($this->getFileObjects()) >= $this->options['max_number_of_files'])
336
+        ) {
337
+            $file->error = 'maxNumberOfFiles';
338
+            return false;
339
+        }
340
+        list($img_width, $img_height) = @getimagesize($uploaded_file);
341
+        if (is_numeric($img_width)) {
342
+            if ($this->options['max_width'] && $img_width > $this->options['max_width'] ||
343
+                    $this->options['max_height'] && $img_height > $this->options['max_height']) {
344
+                $file->error = 'maxResolution';
345
+                return false;
346
+            }
347
+            if ($this->options['min_width'] && $img_width < $this->options['min_width'] ||
348
+                    $this->options['min_height'] && $img_height < $this->options['min_height']) {
349
+                $file->error = 'minResolution';
350
+                return false;
351
+            }
352
+        }
353
+        return true;
354
+    }
355
+
356
+    /**
357
+     * Enter description here ...
358
+     *
359
+     * @param 	int		$matches		???
360
+     * @return	string					???
361
+     */
362
+    protected function upcountNameCallback($matches)
363
+    {
364
+        $index = isset($matches[1]) ? intval($matches[1]) + 1 : 1;
365
+        $ext = isset($matches[2]) ? $matches[2] : '';
366
+        return ' ('.$index.')'.$ext;
367
+    }
368
+
369
+    /**
370
+     * Enter description here ...
371
+     *
372
+     * @param 	string		$name		???
373
+     * @return	string					???
374
+     */
375
+    protected function upcountName($name)
376
+    {
377
+        return preg_replace_callback('/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/', array($this, 'upcountNameCallback'), $name, 1);
378
+    }
379
+
380
+    /**
381
+     * trimFileName
382
+     *
383
+     * @param 	string $name		Filename
384
+     * @param 	string $type		???
385
+     * @param 	string $index		???
386
+     * @return	string
387
+     */
388
+    protected function trimFileName($name, $type, $index)
389
+    {
390
+        // Remove path information and dots around the filename, to prevent uploading
391
+        // into different directories or replacing hidden system files.
392
+        // Also remove control characters and spaces (\x00..\x20) around the filename:
393
+        $file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
394
+        // Add missing file extension for known image types:
395
+        if (strpos($file_name, '.') === false &&
396
+                preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
397
+            $file_name .= '.'.$matches[1];
398
+        }
399
+        if ($this->options['discard_aborted_uploads'])
400
+        {
401
+            while(is_file($this->options['upload_dir'].$file_name))
402
+            {
403
+                $file_name = $this->upcountName($file_name);
404
+            }
405
+        }
406
+        return $file_name;
407
+    }
408
+
409
+    /**
410
+     * handleFileUpload
411
+     *
412
+     * @param 	string		$uploaded_file		Uploade file
413
+     * @param 	string		$name				Name
414
+     * @param 	int			$size				Size
415
+     * @param 	string		$type				Type
416
+     * @param 	string		$error				Error
417
+     * @param	string		$index				Index
418
+     * @return stdClass
419
+     */
420
+    protected function handleFileUpload($uploaded_file, $name, $size, $type, $error, $index)
421
+    {
422
+        $file = new stdClass();
423
+        $file->name = $this->trimFileName($name, $type, $index);
424
+        $file->mime = dol_mimetype($file->name,'',2);
425
+        $file->size = intval($size);
426
+        $file->type = $type;
427
+        if ($this->validate($uploaded_file, $file, $error, $index) && dol_mkdir($this->options['upload_dir']) >= 0)
428
+        {
429
+            $file_path = $this->options['upload_dir'].$file->name;
430
+            $append_file = !$this->options['discard_aborted_uploads'] && is_file($file_path) && $file->size > filesize($file_path);
431
+            clearstatcache();
432
+            if ($uploaded_file && is_uploaded_file($uploaded_file)) {
433
+                // multipart/formdata uploads (POST method uploads)
434
+                if ($append_file)
435
+                {
436
+                    file_put_contents($file_path, fopen($uploaded_file, 'r'), FILE_APPEND);
437
+                } else {
438
+                    dol_move_uploaded_file($uploaded_file, $file_path, 1, 0, 0, 0, 'userfile');
439
+                }
440
+            }
441
+            else
442
+            {
443
+                // Non-multipart uploads (PUT method support)
444
+                file_put_contents($file_path, fopen('php://input', 'r'), $append_file ? FILE_APPEND : 0);
445
+            }
446
+            $file_size = filesize($file_path);
447
+            if ($file_size === $file->size)
448
+            {
449
+                $file->url = $this->options['upload_url'].rawurlencode($file->name);
450
+                foreach($this->options['image_versions'] as $version => $options)
451
+                {
452
+                    if ($this->createScaledImage($file->name, $options))
453
+                    {
454
+                        $tmp=explode('.',$file->name);
455
+                        $file->{$version.'_url'} = $options['upload_url'].rawurlencode($tmp[0].'_mini.'.$tmp[1]);
456
+                    }
457
+                }
458
+            }
459
+            else if ($this->options['discard_aborted_uploads'])
460
+            {
461
+                unlink($file_path);
462
+                $file->error = 'abort';
463
+            }
464
+            $file->size = $file_size;
465
+            $this->setFileDeleteUrl($file);
466
+        }
467
+        return $file;
468
+    }
469
+
470
+    /**
471
+     * Output data
472
+     *
473
+     * @return	void
474
+     */
475
+    public function get()
476
+    {
477
+        $file_name = isset($_REQUEST['file']) ?
478
+        basename(stripslashes($_REQUEST['file'])) : null;
479
+        if ($file_name)
480
+        {
481
+            $info = $this->getFileObject($file_name);
482
+        }
483
+        else
484
+        {
485
+            $info = $this->getFileObjects();
486
+        }
487
+        header('Content-type: application/json');
488
+        echo json_encode($info);
489
+    }
490
+
491
+    /**
492
+     * Output data
493
+     *
494
+     * @return	void
495
+     */
496
+    public function post()
497
+    {
498
+        if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE')
499
+        {
500
+            return $this->delete();
501
+        }
502
+        $upload = isset($_FILES[$this->options['param_name']]) ?
503
+        $_FILES[$this->options['param_name']] : null;
504
+        $info = array();
505
+        if ($upload && is_array($upload['tmp_name']))
506
+        {
507
+            // param_name is an array identifier like "files[]",
508
+            // $_FILES is a multi-dimensional array:
509
+            foreach ($upload['tmp_name'] as $index => $value) {
510 510
                 $info[] = $this->handleFileUpload(
511 511
                     $upload['tmp_name'][$index],
512 512
                     isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
@@ -515,10 +515,10 @@  discard block
 block discarded – undo
515 515
                     $upload['error'][$index],
516 516
                     $index
517 517
                 );
518
-			}
519
-		} elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
520
-			// param_name is a single object identifier like "file",
521
-			// $_FILES is a one-dimensional array:
518
+            }
519
+        } elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
520
+            // param_name is a single object identifier like "file",
521
+            // $_FILES is a one-dimensional array:
522 522
             $info[] = $this->handleFileUpload(
523 523
                 isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
524 524
                 isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : (isset($upload['name']) ? $upload['name'] : null),
@@ -527,47 +527,47 @@  discard block
 block discarded – undo
527 527
                 isset($upload['error']) ? $upload['error'] : null,
528 528
                 0
529 529
             );
530
-		}
531
-		header('Vary: Accept');
532
-		$json = json_encode($info);
533
-		$redirect = isset($_REQUEST['redirect']) ?
534
-		stripslashes($_REQUEST['redirect']) : null;
535
-		if ($redirect) {
536
-			header('Location: '.sprintf($redirect, rawurlencode($json)));
537
-			return;
538
-		}
539
-		if (isset($_SERVER['HTTP_ACCEPT']) &&
540
-				(strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
541
-			header('Content-type: application/json');
542
-		} else {
543
-			header('Content-type: text/plain');
544
-		}
545
-		echo $json;
546
-	}
547
-
548
-	/**
549
-	 * Delete uploaded file
550
-	 *
551
-	 * @return	void
552
-	 */
553
-	public function delete()
554
-	{
555
-		$file_name = isset($_REQUEST['file']) ?
556
-		basename(stripslashes($_REQUEST['file'])) : null;
557
-		$file_path = $this->options['upload_dir'].$file_name;
558
-		$success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
559
-		if ($success)
560
-		{
561
-			foreach($this->options['image_versions'] as $version => $options)
562
-			{
563
-				$file = $options['upload_dir'].$file_name;
564
-				if (is_file($file))
565
-				{
566
-					unlink($file);
567
-				}
568
-			}
569
-		}
570
-		header('Content-type: application/json');
571
-		echo json_encode($success);
572
-	}
530
+        }
531
+        header('Vary: Accept');
532
+        $json = json_encode($info);
533
+        $redirect = isset($_REQUEST['redirect']) ?
534
+        stripslashes($_REQUEST['redirect']) : null;
535
+        if ($redirect) {
536
+            header('Location: '.sprintf($redirect, rawurlencode($json)));
537
+            return;
538
+        }
539
+        if (isset($_SERVER['HTTP_ACCEPT']) &&
540
+                (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
541
+            header('Content-type: application/json');
542
+        } else {
543
+            header('Content-type: text/plain');
544
+        }
545
+        echo $json;
546
+    }
547
+
548
+    /**
549
+     * Delete uploaded file
550
+     *
551
+     * @return	void
552
+     */
553
+    public function delete()
554
+    {
555
+        $file_name = isset($_REQUEST['file']) ?
556
+        basename(stripslashes($_REQUEST['file'])) : null;
557
+        $file_path = $this->options['upload_dir'].$file_name;
558
+        $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
559
+        if ($success)
560
+        {
561
+            foreach($this->options['image_versions'] as $version => $options)
562
+            {
563
+                $file = $options['upload_dir'].$file_name;
564
+                if (is_file($file))
565
+                {
566
+                    unlink($file);
567
+                }
568
+            }
569
+        }
570
+        header('Content-type: application/json');
571
+        echo json_encode($success);
572
+    }
573 573
 }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/html.formprojet.class.php 1 patch
Indentation   +616 added lines, -616 removed lines patch added patch discarded remove patch
@@ -29,660 +29,660 @@
 block discarded – undo
29 29
  */
30 30
 class FormProjets
31 31
 {
32
-	/**
32
+    /**
33 33
      * @var DoliDB Database handler.
34 34
      */
35 35
     public $db;
36 36
 
37
-	/**
38
-	 * @var string Error code (or message)
39
-	 */
40
-	public $error='';
37
+    /**
38
+     * @var string Error code (or message)
39
+     */
40
+    public $error='';
41 41
 
42 42
 
43
-	/**
44
-	 *	Constructor
45
-	 *
46
-	 *  @param		DoliDB		$db      Database handler
47
-	 */
48
-	function __construct($db)
49
-	{
50
-		$this->db = $db;
51
-	}
43
+    /**
44
+     *	Constructor
45
+     *
46
+     *  @param		DoliDB		$db      Database handler
47
+     */
48
+    function __construct($db)
49
+    {
50
+        $this->db = $db;
51
+    }
52 52
 
53 53
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
54
-	/**
55
-	 *	Output a combo list with projects qualified for a third party / user
56
-	 *
57
-	 *	@param	int		$socid      	Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
58
-	 *	@param  string	$selected   	Id project preselected ('' or id of project)
59
-	 *	@param  string	$htmlname   	Name of HTML field
60
-	 *	@param	int		$maxlength		Maximum length of label
61
-	 *	@param	int		$option_only	Return only html options lines without the select tag
62
-	 *	@param	int		$show_empty		Add an empty line
63
-	 *  @param	int		$discard_closed Discard closed projects (0=Keep,1=hide completely,2=Disable)
64
-	 *  @param	int		$forcefocus		Force focus on field (works with javascript only)
65
-	 *  @param	int		$disabled		Disabled
66
-	 *  @param  int     $mode           0 for HTML mode and 1 for JSON mode
67
-	 *  @param  string  $filterkey      Key to filter
68
-	 *  @param  int     $nooutput       No print output. Return it only.
69
-	 *  @param  int     $forceaddid     Force to add project id in list, event if not qualified
70
-	 *  @param  string  $morecss        More css
71
-	 *	@param  int     $htmlid         Html id to use instead of htmlname
72
-	 *	@return string           		Return html content
73
-	 */
74
-	function select_projects($socid=-1, $selected='', $htmlname='projectid', $maxlength=16, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode = 0, $filterkey = '', $nooutput=0, $forceaddid=0, $morecss='', $htmlid='')
75
-	{
54
+    /**
55
+     *	Output a combo list with projects qualified for a third party / user
56
+     *
57
+     *	@param	int		$socid      	Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
58
+     *	@param  string	$selected   	Id project preselected ('' or id of project)
59
+     *	@param  string	$htmlname   	Name of HTML field
60
+     *	@param	int		$maxlength		Maximum length of label
61
+     *	@param	int		$option_only	Return only html options lines without the select tag
62
+     *	@param	int		$show_empty		Add an empty line
63
+     *  @param	int		$discard_closed Discard closed projects (0=Keep,1=hide completely,2=Disable)
64
+     *  @param	int		$forcefocus		Force focus on field (works with javascript only)
65
+     *  @param	int		$disabled		Disabled
66
+     *  @param  int     $mode           0 for HTML mode and 1 for JSON mode
67
+     *  @param  string  $filterkey      Key to filter
68
+     *  @param  int     $nooutput       No print output. Return it only.
69
+     *  @param  int     $forceaddid     Force to add project id in list, event if not qualified
70
+     *  @param  string  $morecss        More css
71
+     *	@param  int     $htmlid         Html id to use instead of htmlname
72
+     *	@return string           		Return html content
73
+     */
74
+    function select_projects($socid=-1, $selected='', $htmlname='projectid', $maxlength=16, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode = 0, $filterkey = '', $nooutput=0, $forceaddid=0, $morecss='', $htmlid='')
75
+    {
76 76
         // phpcs:enable
77
-		global $langs,$conf,$form;
78
-
79
-		$out='';
80
-
81
-		if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_SEARCH_TO_SELECT))
82
-		{
83
-			$placeholder='';
84
-
85
-			if ($selected && empty($selected_input_value))
86
-			{
87
-				require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
88
-				$project = new Project($this->db);
89
-				$project->fetch($selected);
90
-				$selected_input_value=$project->ref;
91
-			}
92
-			$urloption='socid='.$socid.'&htmlname='.$htmlname.'&discardclosed='.$discard_closed;
93
-			$out.=ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array(
77
+        global $langs,$conf,$form;
78
+
79
+        $out='';
80
+
81
+        if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_SEARCH_TO_SELECT))
82
+        {
83
+            $placeholder='';
84
+
85
+            if ($selected && empty($selected_input_value))
86
+            {
87
+                require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
88
+                $project = new Project($this->db);
89
+                $project->fetch($selected);
90
+                $selected_input_value=$project->ref;
91
+            }
92
+            $urloption='socid='.$socid.'&htmlname='.$htmlname.'&discardclosed='.$discard_closed;
93
+            $out.=ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array(
94 94
 //				'update' => array(
95 95
 //					'projectid' => 'id'
96 96
 //				)
97
-			));
98
-
99
-			$out.='<input type="text" class="minwidth200'.($morecss?' '.$morecss:'').'" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' />';
100
-		}
101
-		else
102
-		{
103
-			$out.=$this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, $discard_closed, $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss);
104
-		}
105
-		if ($discard_closed)
106
-		{
107
-			if (class_exists('Form'))
108
-			{
109
-				if (empty($form)) $form=new Form($this->db);
110
-				$out.=$form->textwithpicto('', $langs->trans("ClosedProjectsAreHidden"));
111
-			}
112
-		}
113
-
114
-		if (empty($nooutput))
115
-		{
116
-		    print $out;
117
-		    return '';
118
-		}
119
-		else return $out;
120
-	}
97
+            ));
98
+
99
+            $out.='<input type="text" class="minwidth200'.($morecss?' '.$morecss:'').'" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' />';
100
+        }
101
+        else
102
+        {
103
+            $out.=$this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, $discard_closed, $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss);
104
+        }
105
+        if ($discard_closed)
106
+        {
107
+            if (class_exists('Form'))
108
+            {
109
+                if (empty($form)) $form=new Form($this->db);
110
+                $out.=$form->textwithpicto('', $langs->trans("ClosedProjectsAreHidden"));
111
+            }
112
+        }
113
+
114
+        if (empty($nooutput))
115
+        {
116
+            print $out;
117
+            return '';
118
+        }
119
+        else return $out;
120
+    }
121 121
 
122 122
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
123
-	/**
124
-	 * Returns an array with projects qualified for a third party
125
-	 *
126
-	 * @param  int     $socid      	       Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
127
-	 * @param  int     $selected   	       Id project preselected
128
-	 * @param  string  $htmlname   	       Nom de la zone html
129
-	 * @param  int     $maxlength          Maximum length of label
130
-	 * @param  int     $option_only	       Return only html options lines without the select tag
131
-	 * @param  int     $show_empty		   Add an empty line
132
-	 * @param  int     $discard_closed     Discard closed projects (0=Keep,1=hide completely,2=Disable)
123
+    /**
124
+     * Returns an array with projects qualified for a third party
125
+     *
126
+     * @param  int     $socid      	       Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
127
+     * @param  int     $selected   	       Id project preselected
128
+     * @param  string  $htmlname   	       Nom de la zone html
129
+     * @param  int     $maxlength          Maximum length of label
130
+     * @param  int     $option_only	       Return only html options lines without the select tag
131
+     * @param  int     $show_empty		   Add an empty line
132
+     * @param  int     $discard_closed     Discard closed projects (0=Keep,1=hide completely,2=Disable)
133 133
      * @param  int     $forcefocus		   Force focus on field (works with javascript only)
134 134
      * @param  int     $disabled           Disabled
135
-	 * @param  int     $mode               0 for HTML mode and 1 for array return (to be used by json_encode for example)
136
-	 * @param  string  $filterkey          Key to filter
137
-	 * @param  int     $nooutput           No print output. Return it only.
138
-	 * @param  int     $forceaddid         Force to add project id in list, event if not qualified
139
-	 * @param  int     $htmlid             Html id to use instead of htmlname
140
-	 * @param  string  $morecss            More CSS
141
-	 * @return int         			       Nb of project if OK, <0 if KO
142
-	 */
143
-	function select_projects_list($socid=-1, $selected='', $htmlname='projectid', $maxlength=24, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode=0, $filterkey = '', $nooutput=0, $forceaddid=0, $htmlid='', $morecss='maxwidth500')
144
-	{
135
+     * @param  int     $mode               0 for HTML mode and 1 for array return (to be used by json_encode for example)
136
+     * @param  string  $filterkey          Key to filter
137
+     * @param  int     $nooutput           No print output. Return it only.
138
+     * @param  int     $forceaddid         Force to add project id in list, event if not qualified
139
+     * @param  int     $htmlid             Html id to use instead of htmlname
140
+     * @param  string  $morecss            More CSS
141
+     * @return int         			       Nb of project if OK, <0 if KO
142
+     */
143
+    function select_projects_list($socid=-1, $selected='', $htmlname='projectid', $maxlength=24, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode=0, $filterkey = '', $nooutput=0, $forceaddid=0, $htmlid='', $morecss='maxwidth500')
144
+    {
145 145
         // phpcs:enable
146
-		global $user,$conf,$langs;
147
-
148
-		require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
149
-
150
-		if (empty($htmlid)) $htmlid = $htmlname;
151
-
152
-		$out='';
153
-		$outarray=array();
154
-
155
-		$hideunselectables = false;
156
-		if (! empty($conf->global->CONTRACT_HIDE_UNSELECTABLES)) $hideunselectables = true;
157
-
158
-		$projectsListId = false;
159
-		if (empty($user->rights->projet->all->lire))
160
-		{
161
-			$projectstatic=new Project($this->db);
162
-			$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1);
163
-		}
164
-
165
-		// Search all projects
166
-		$sql = 'SELECT p.rowid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public, s.nom as name, s.name_alias';
167
-		$sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p LEFT JOIN '.MAIN_DB_PREFIX .'societe as s ON s.rowid = p.fk_soc';
168
-		$sql.= " WHERE p.entity IN (".getEntity('project').")";
169
-		if ($projectsListId !== false) $sql.= " AND p.rowid IN (".$projectsListId.")";
170
-		if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)";
171
-		if ($socid > 0)
172
-		{
173
-		    if (empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY))  $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)";
174
-		    else if ($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY != 'all')    // PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY is 'all' or a list of ids separated by coma.
175
-		    {
176
-		        $sql.= " AND (p.fk_soc IN (".$socid.", ".$conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY.") OR p.fk_soc IS NULL)";
177
-		    }
178
-		}
179
-		if (!empty($filterkey)) $sql .= natural_search(array('p.title', 'p.ref'), $filterkey);
180
-		$sql.= " ORDER BY p.ref ASC";
181
-
182
-		$resql=$this->db->query($sql);
183
-		if ($resql)
184
-		{
185
-			// Use select2 selector
186
-			if (! empty($conf->use_javascript_ajax))
187
-			{
188
-				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
189
-	           	$comboenhancement = ajax_combobox($htmlid, array(), 0, $forcefocus);
190
-            	$out.=$comboenhancement;
191
-            	$morecss.=' minwidth100';
192
-			}
193
-
194
-			if (empty($option_only)) {
195
-				$out.= '<select class="flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlid.'" name="'.$htmlname.'">';
196
-			}
197
-			if (!empty($show_empty)) {
198
-				$out.= '<option value="0">&nbsp;</option>';
199
-			}
200
-			$num = $this->db->num_rows($resql);
201
-			$i = 0;
202
-			if ($num)
203
-			{
204
-				while ($i < $num)
205
-				{
206
-					$obj = $this->db->fetch_object($resql);
207
-					// If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project.
208
-					if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && ! $user->rights->societe->lire)
209
-					{
210
-						// Do nothing
211
-					}
212
-					else
213
-					{
214
-						if ($discard_closed == 1 && $obj->fk_statut == 2 && $obj->rowid != $selected) // We discard closed except if selected
215
-						{
216
-							$i++;
217
-							continue;
218
-						}
219
-
220
-						$labeltoshow=dol_trunc($obj->ref,18);
221
-						//if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')';
222
-						//else $labeltoshow.=' ('.$langs->trans("Private").')';
223
-						$labeltoshow.=', '.dol_trunc($obj->title, $maxlength);
224
-						if ($obj->name)
225
-						{
226
-						    $labeltoshow.=' - '.$obj->name;
227
-						    if ($obj->name_alias) $labeltoshow.=' ('.$obj->name_alias.')';
228
-						}
229
-
230
-						$disabled=0;
231
-						if ($obj->fk_statut == 0)
232
-						{
233
-							$disabled=1;
234
-							$labeltoshow.=' - '.$langs->trans("Draft");
235
-						}
236
-						else if ($obj->fk_statut == 2)
237
-						{
238
-							if ($discard_closed == 2) $disabled=1;
239
-							$labeltoshow.=' - '.$langs->trans("Closed");
240
-						}
241
-						else if ( empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY) &&  $socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
242
-						{
243
-							$disabled=1;
244
-							$labeltoshow.=' - '.$langs->trans("LinkedToAnotherCompany");
245
-						}
246
-
247
-						if (!empty($selected) && $selected == $obj->rowid)
248
-						{
249
-							$out.= '<option value="'.$obj->rowid.'" selected';
250
-							//if ($disabled) $out.=' disabled';						// with select2, field can't be preselected if disabled
251
-							$out.= '>'.$labeltoshow.'</option>';
252
-						}
253
-						else
254
-						{
255
-							if ($hideunselectables && $disabled && ($selected != $obj->rowid))
256
-							{
257
-								$resultat='';
258
-							}
259
-							else
260
-							{
261
-								$resultat='<option value="'.$obj->rowid.'"';
262
-								if ($disabled) $resultat.=' disabled';
263
-								//if ($obj->public) $labeltoshow.=' ('.$langs->trans("Public").')';
264
-								//else $labeltoshow.=' ('.$langs->trans("Private").')';
265
-								$resultat.='>';
266
-								$resultat.=$labeltoshow;
267
-								$resultat.='</option>';
268
-							}
269
-							$out.= $resultat;
270
-
271
-							$outarray[] = array(
272
-								'key' => (int) $obj->rowid,
273
-								'value' => $obj->ref,
274
-								'ref' => $obj->ref,
275
-								'label' => $labeltoshow,
276
-								'disabled' => (bool) $disabled
277
-							);
278
-						}
279
-					}
280
-					$i++;
281
-				}
282
-			}
283
-
284
-			$this->db->free($resql);
285
-
286
-			if (!$mode) {
287
-				if (empty($option_only)) $out.= '</select>';
288
-				if (empty($nooutput))
289
-				{
290
-				    print $out;
291
-				    return '';
292
-				}
293
-				else return $out;
294
-			} else {
295
-				return $outarray;
296
-			}
297
-		}
298
-		else
299
-		{
300
-			dol_print_error($this->db);
301
-			return -1;
302
-		}
303
-	}
304
-
305
-	/**
306
-	 *	Output a combo list with tasks qualified for a third party
307
-	 *
308
-	 *	@param	int		$socid      	Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
309
-	 *	@param  int		$selected   	Id task preselected
310
-	 *	@param  string	$htmlname   	Name of HTML select
311
-	 *	@param	int		$maxlength		Maximum length of label
312
-	 *	@param	int		$option_only	Return only html options lines without the select tag
313
-	 *	@param	string	$show_empty		Add an empty line ('1' or string to show for empty line)
314
-	 *  @param	int		$discard_closed Discard closed projects (0=Keep,1=hide completely,2=Disable)
146
+        global $user,$conf,$langs;
147
+
148
+        require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
149
+
150
+        if (empty($htmlid)) $htmlid = $htmlname;
151
+
152
+        $out='';
153
+        $outarray=array();
154
+
155
+        $hideunselectables = false;
156
+        if (! empty($conf->global->CONTRACT_HIDE_UNSELECTABLES)) $hideunselectables = true;
157
+
158
+        $projectsListId = false;
159
+        if (empty($user->rights->projet->all->lire))
160
+        {
161
+            $projectstatic=new Project($this->db);
162
+            $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1);
163
+        }
164
+
165
+        // Search all projects
166
+        $sql = 'SELECT p.rowid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public, s.nom as name, s.name_alias';
167
+        $sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p LEFT JOIN '.MAIN_DB_PREFIX .'societe as s ON s.rowid = p.fk_soc';
168
+        $sql.= " WHERE p.entity IN (".getEntity('project').")";
169
+        if ($projectsListId !== false) $sql.= " AND p.rowid IN (".$projectsListId.")";
170
+        if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)";
171
+        if ($socid > 0)
172
+        {
173
+            if (empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY))  $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)";
174
+            else if ($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY != 'all')    // PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY is 'all' or a list of ids separated by coma.
175
+            {
176
+                $sql.= " AND (p.fk_soc IN (".$socid.", ".$conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY.") OR p.fk_soc IS NULL)";
177
+            }
178
+        }
179
+        if (!empty($filterkey)) $sql .= natural_search(array('p.title', 'p.ref'), $filterkey);
180
+        $sql.= " ORDER BY p.ref ASC";
181
+
182
+        $resql=$this->db->query($sql);
183
+        if ($resql)
184
+        {
185
+            // Use select2 selector
186
+            if (! empty($conf->use_javascript_ajax))
187
+            {
188
+                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
189
+                    $comboenhancement = ajax_combobox($htmlid, array(), 0, $forcefocus);
190
+                $out.=$comboenhancement;
191
+                $morecss.=' minwidth100';
192
+            }
193
+
194
+            if (empty($option_only)) {
195
+                $out.= '<select class="flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlid.'" name="'.$htmlname.'">';
196
+            }
197
+            if (!empty($show_empty)) {
198
+                $out.= '<option value="0">&nbsp;</option>';
199
+            }
200
+            $num = $this->db->num_rows($resql);
201
+            $i = 0;
202
+            if ($num)
203
+            {
204
+                while ($i < $num)
205
+                {
206
+                    $obj = $this->db->fetch_object($resql);
207
+                    // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project.
208
+                    if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && ! $user->rights->societe->lire)
209
+                    {
210
+                        // Do nothing
211
+                    }
212
+                    else
213
+                    {
214
+                        if ($discard_closed == 1 && $obj->fk_statut == 2 && $obj->rowid != $selected) // We discard closed except if selected
215
+                        {
216
+                            $i++;
217
+                            continue;
218
+                        }
219
+
220
+                        $labeltoshow=dol_trunc($obj->ref,18);
221
+                        //if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')';
222
+                        //else $labeltoshow.=' ('.$langs->trans("Private").')';
223
+                        $labeltoshow.=', '.dol_trunc($obj->title, $maxlength);
224
+                        if ($obj->name)
225
+                        {
226
+                            $labeltoshow.=' - '.$obj->name;
227
+                            if ($obj->name_alias) $labeltoshow.=' ('.$obj->name_alias.')';
228
+                        }
229
+
230
+                        $disabled=0;
231
+                        if ($obj->fk_statut == 0)
232
+                        {
233
+                            $disabled=1;
234
+                            $labeltoshow.=' - '.$langs->trans("Draft");
235
+                        }
236
+                        else if ($obj->fk_statut == 2)
237
+                        {
238
+                            if ($discard_closed == 2) $disabled=1;
239
+                            $labeltoshow.=' - '.$langs->trans("Closed");
240
+                        }
241
+                        else if ( empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY) &&  $socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
242
+                        {
243
+                            $disabled=1;
244
+                            $labeltoshow.=' - '.$langs->trans("LinkedToAnotherCompany");
245
+                        }
246
+
247
+                        if (!empty($selected) && $selected == $obj->rowid)
248
+                        {
249
+                            $out.= '<option value="'.$obj->rowid.'" selected';
250
+                            //if ($disabled) $out.=' disabled';						// with select2, field can't be preselected if disabled
251
+                            $out.= '>'.$labeltoshow.'</option>';
252
+                        }
253
+                        else
254
+                        {
255
+                            if ($hideunselectables && $disabled && ($selected != $obj->rowid))
256
+                            {
257
+                                $resultat='';
258
+                            }
259
+                            else
260
+                            {
261
+                                $resultat='<option value="'.$obj->rowid.'"';
262
+                                if ($disabled) $resultat.=' disabled';
263
+                                //if ($obj->public) $labeltoshow.=' ('.$langs->trans("Public").')';
264
+                                //else $labeltoshow.=' ('.$langs->trans("Private").')';
265
+                                $resultat.='>';
266
+                                $resultat.=$labeltoshow;
267
+                                $resultat.='</option>';
268
+                            }
269
+                            $out.= $resultat;
270
+
271
+                            $outarray[] = array(
272
+                                'key' => (int) $obj->rowid,
273
+                                'value' => $obj->ref,
274
+                                'ref' => $obj->ref,
275
+                                'label' => $labeltoshow,
276
+                                'disabled' => (bool) $disabled
277
+                            );
278
+                        }
279
+                    }
280
+                    $i++;
281
+                }
282
+            }
283
+
284
+            $this->db->free($resql);
285
+
286
+            if (!$mode) {
287
+                if (empty($option_only)) $out.= '</select>';
288
+                if (empty($nooutput))
289
+                {
290
+                    print $out;
291
+                    return '';
292
+                }
293
+                else return $out;
294
+            } else {
295
+                return $outarray;
296
+            }
297
+        }
298
+        else
299
+        {
300
+            dol_print_error($this->db);
301
+            return -1;
302
+        }
303
+    }
304
+
305
+    /**
306
+     *	Output a combo list with tasks qualified for a third party
307
+     *
308
+     *	@param	int		$socid      	Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id)
309
+     *	@param  int		$selected   	Id task preselected
310
+     *	@param  string	$htmlname   	Name of HTML select
311
+     *	@param	int		$maxlength		Maximum length of label
312
+     *	@param	int		$option_only	Return only html options lines without the select tag
313
+     *	@param	string	$show_empty		Add an empty line ('1' or string to show for empty line)
314
+     *  @param	int		$discard_closed Discard closed projects (0=Keep,1=hide completely,2=Disable)
315 315
      *  @param	int		$forcefocus		Force focus on field (works with javascript only)
316 316
      *  @param	int		$disabled		Disabled
317
-	 *  @param	string	$morecss        More css added to the select component
318
-	 *  @param	string	$projectsListId ''=Automatic filter on project allowed. List of id=Filter on project ids.
319
-	 *  @param	string	$showproject	'all' = Show project info, ''=Hide project info
320
-	 *  @param	User	$usertofilter	User object to use for filtering
321
-	 *	@return int         			Nbr of project if OK, <0 if KO
322
-	 */
323
-	function selectTasks($socid=-1, $selected='', $htmlname='taskid', $maxlength=24, $option_only=0, $show_empty='1', $discard_closed=0, $forcefocus=0, $disabled=0, $morecss='maxwidth500', $projectsListId='', $showproject='all', $usertofilter=null)
324
-	{
325
-		global $user,$conf,$langs;
326
-
327
-		require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
328
-
329
-		if (is_null($usertofilter))
330
-		{
331
-			$usertofilter = $user;
332
-		}
333
-
334
-		$out='';
335
-
336
-		$hideunselectables = false;
337
-		if (! empty($conf->global->PROJECT_HIDE_UNSELECTABLES)) $hideunselectables = true;
338
-
339
-		if (empty($projectsListId))
340
-		{
341
-			if (empty($usertofilter->rights->projet->all->lire))
342
-			{
343
-				$projectstatic=new Project($this->db);
344
-				$projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertofilter,0,1);
345
-			}
346
-		}
347
-
348
-		// Search all projects
349
-		$sql = 'SELECT t.rowid, t.ref as tref, t.label as tlabel, p.rowid as pid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public,';
350
-		$sql.= ' s.nom as name';
351
-		$sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p';
352
-		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = p.fk_soc,';
353
-		$sql.= ' '.MAIN_DB_PREFIX.'projet_task as t';
354
-		$sql.= " WHERE p.entity IN (".getEntity('project').")";
355
-		$sql.= " AND t.fk_projet = p.rowid";
356
-		if ($projectsListId) $sql.= " AND p.rowid IN (".$projectsListId.")";
357
-		if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)";
358
-		if ($socid > 0)  $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)";
359
-		$sql.= " ORDER BY p.ref, t.ref ASC";
360
-
361
-		$resql=$this->db->query($sql);
362
-		if ($resql)
363
-		{
364
-			// Use select2 selector
365
-			if (! empty($conf->use_javascript_ajax))
366
-			{
367
-				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
368
-	           	$comboenhancement = ajax_combobox($htmlname, '', 0, $forcefocus);
369
-            	$out.=$comboenhancement;
370
-            	$morecss='minwidth200 maxwidth500';
371
-			}
372
-
373
-			if (empty($option_only)) {
374
-				$out.= '<select class="valignmiddle flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlname.'" name="'.$htmlname.'">';
375
-			}
376
-			if (! empty($show_empty)) {
377
-				$out.= '<option value="0" class="optiongrey">';
378
-				if (! is_numeric($show_empty)) $out.=$show_empty;
379
-				else $out.='&nbsp;';
380
-				$out.= '</option>';
381
-			}
382
-			$num = $this->db->num_rows($resql);
383
-			$i = 0;
384
-			if ($num)
385
-			{
386
-				while ($i < $num)
387
-				{
388
-					$obj = $this->db->fetch_object($resql);
389
-					// If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project.
390
-					if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && empty($usertofilter->rights->societe->lire))
391
-					{
392
-						// Do nothing
393
-					}
394
-					else
395
-					{
396
-						if ($discard_closed == 1 && $obj->fk_statut == Project::STATUS_CLOSED)
397
-						{
398
-							$i++;
399
-							continue;
400
-						}
401
-
402
-						$labeltoshow = '';
403
-
404
-						if ($showproject == 'all')
405
-						{
406
-							$labeltoshow.=dol_trunc($obj->ref,18);     // Project ref
407
-							//if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')';
408
-							//else $labeltoshow.=' ('.$langs->trans("Private").')';
409
-							$labeltoshow.=' '.dol_trunc($obj->title,$maxlength);
410
-
411
-							if ($obj->name) $labeltoshow.=' ('.$obj->name.')';
412
-
413
-							$disabled=0;
414
-							if ($obj->fk_statut == Project::STATUS_DRAFT)
415
-							{
416
-								$disabled=1;
417
-								$labeltoshow.=' - '.$langs->trans("Draft");
418
-							}
419
-							else if ($obj->fk_statut == Project::STATUS_CLOSED)
420
-							{
421
-								if ($discard_closed == 2) $disabled=1;
422
-								$labeltoshow.=' - '.$langs->trans("Closed");
423
-							}
424
-							else if ($socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
425
-							{
426
-								$disabled=1;
427
-								$labeltoshow.=' - '.$langs->trans("LinkedToAnotherCompany");
428
-							}
429
-							$labeltoshow.=' - ';
430
-						}
431
-
432
-						// Label for task
433
-						$labeltoshow.=$obj->tref.' '.dol_trunc($obj->tlabel,$maxlength);
434
-
435
-						if (!empty($selected) && $selected == $obj->rowid)
436
-						{
437
-							$out.= '<option value="'.$obj->rowid.'" selected';
438
-							//if ($disabled) $out.=' disabled';						// with select2, field can't be preselected if disabled
439
-							$out.= '>'.$labeltoshow.'</option>';
440
-						}
441
-						else
442
-						{
443
-							if ($hideunselectables && $disabled && ($selected != $obj->rowid))
444
-							{
445
-								$resultat='';
446
-							}
447
-							else
448
-							{
449
-								$resultat='<option value="'.$obj->rowid.'"';
450
-								if ($disabled) $resultat.=' disabled';
451
-								//if ($obj->public) $labeltoshow.=' ('.$langs->trans("Public").')';
452
-								//else $labeltoshow.=' ('.$langs->trans("Private").')';
453
-								$resultat.='>';
454
-								$resultat.=$labeltoshow;
455
-								$resultat.='</option>';
456
-							}
457
-							$out.= $resultat;
458
-						}
459
-					}
460
-					$i++;
461
-				}
462
-			}
463
-			if (empty($option_only)) {
464
-				$out.= '</select>';
465
-			}
466
-
467
-			print $out;
468
-
469
-			$this->db->free($resql);
470
-			return $num;
471
-		}
472
-		else
473
-		{
474
-			dol_print_error($this->db);
475
-			return -1;
476
-		}
477
-	}
317
+     *  @param	string	$morecss        More css added to the select component
318
+     *  @param	string	$projectsListId ''=Automatic filter on project allowed. List of id=Filter on project ids.
319
+     *  @param	string	$showproject	'all' = Show project info, ''=Hide project info
320
+     *  @param	User	$usertofilter	User object to use for filtering
321
+     *	@return int         			Nbr of project if OK, <0 if KO
322
+     */
323
+    function selectTasks($socid=-1, $selected='', $htmlname='taskid', $maxlength=24, $option_only=0, $show_empty='1', $discard_closed=0, $forcefocus=0, $disabled=0, $morecss='maxwidth500', $projectsListId='', $showproject='all', $usertofilter=null)
324
+    {
325
+        global $user,$conf,$langs;
326
+
327
+        require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
328
+
329
+        if (is_null($usertofilter))
330
+        {
331
+            $usertofilter = $user;
332
+        }
333
+
334
+        $out='';
335
+
336
+        $hideunselectables = false;
337
+        if (! empty($conf->global->PROJECT_HIDE_UNSELECTABLES)) $hideunselectables = true;
338
+
339
+        if (empty($projectsListId))
340
+        {
341
+            if (empty($usertofilter->rights->projet->all->lire))
342
+            {
343
+                $projectstatic=new Project($this->db);
344
+                $projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertofilter,0,1);
345
+            }
346
+        }
347
+
348
+        // Search all projects
349
+        $sql = 'SELECT t.rowid, t.ref as tref, t.label as tlabel, p.rowid as pid, p.ref, p.title, p.fk_soc, p.fk_statut, p.public,';
350
+        $sql.= ' s.nom as name';
351
+        $sql.= ' FROM '.MAIN_DB_PREFIX .'projet as p';
352
+        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = p.fk_soc,';
353
+        $sql.= ' '.MAIN_DB_PREFIX.'projet_task as t';
354
+        $sql.= " WHERE p.entity IN (".getEntity('project').")";
355
+        $sql.= " AND t.fk_projet = p.rowid";
356
+        if ($projectsListId) $sql.= " AND p.rowid IN (".$projectsListId.")";
357
+        if ($socid == 0) $sql.= " AND (p.fk_soc=0 OR p.fk_soc IS NULL)";
358
+        if ($socid > 0)  $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)";
359
+        $sql.= " ORDER BY p.ref, t.ref ASC";
360
+
361
+        $resql=$this->db->query($sql);
362
+        if ($resql)
363
+        {
364
+            // Use select2 selector
365
+            if (! empty($conf->use_javascript_ajax))
366
+            {
367
+                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
368
+                    $comboenhancement = ajax_combobox($htmlname, '', 0, $forcefocus);
369
+                $out.=$comboenhancement;
370
+                $morecss='minwidth200 maxwidth500';
371
+            }
372
+
373
+            if (empty($option_only)) {
374
+                $out.= '<select class="valignmiddle flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlname.'" name="'.$htmlname.'">';
375
+            }
376
+            if (! empty($show_empty)) {
377
+                $out.= '<option value="0" class="optiongrey">';
378
+                if (! is_numeric($show_empty)) $out.=$show_empty;
379
+                else $out.='&nbsp;';
380
+                $out.= '</option>';
381
+            }
382
+            $num = $this->db->num_rows($resql);
383
+            $i = 0;
384
+            if ($num)
385
+            {
386
+                while ($i < $num)
387
+                {
388
+                    $obj = $this->db->fetch_object($resql);
389
+                    // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project.
390
+                    if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && empty($usertofilter->rights->societe->lire))
391
+                    {
392
+                        // Do nothing
393
+                    }
394
+                    else
395
+                    {
396
+                        if ($discard_closed == 1 && $obj->fk_statut == Project::STATUS_CLOSED)
397
+                        {
398
+                            $i++;
399
+                            continue;
400
+                        }
401
+
402
+                        $labeltoshow = '';
403
+
404
+                        if ($showproject == 'all')
405
+                        {
406
+                            $labeltoshow.=dol_trunc($obj->ref,18);     // Project ref
407
+                            //if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')';
408
+                            //else $labeltoshow.=' ('.$langs->trans("Private").')';
409
+                            $labeltoshow.=' '.dol_trunc($obj->title,$maxlength);
410
+
411
+                            if ($obj->name) $labeltoshow.=' ('.$obj->name.')';
412
+
413
+                            $disabled=0;
414
+                            if ($obj->fk_statut == Project::STATUS_DRAFT)
415
+                            {
416
+                                $disabled=1;
417
+                                $labeltoshow.=' - '.$langs->trans("Draft");
418
+                            }
419
+                            else if ($obj->fk_statut == Project::STATUS_CLOSED)
420
+                            {
421
+                                if ($discard_closed == 2) $disabled=1;
422
+                                $labeltoshow.=' - '.$langs->trans("Closed");
423
+                            }
424
+                            else if ($socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
425
+                            {
426
+                                $disabled=1;
427
+                                $labeltoshow.=' - '.$langs->trans("LinkedToAnotherCompany");
428
+                            }
429
+                            $labeltoshow.=' - ';
430
+                        }
431
+
432
+                        // Label for task
433
+                        $labeltoshow.=$obj->tref.' '.dol_trunc($obj->tlabel,$maxlength);
434
+
435
+                        if (!empty($selected) && $selected == $obj->rowid)
436
+                        {
437
+                            $out.= '<option value="'.$obj->rowid.'" selected';
438
+                            //if ($disabled) $out.=' disabled';						// with select2, field can't be preselected if disabled
439
+                            $out.= '>'.$labeltoshow.'</option>';
440
+                        }
441
+                        else
442
+                        {
443
+                            if ($hideunselectables && $disabled && ($selected != $obj->rowid))
444
+                            {
445
+                                $resultat='';
446
+                            }
447
+                            else
448
+                            {
449
+                                $resultat='<option value="'.$obj->rowid.'"';
450
+                                if ($disabled) $resultat.=' disabled';
451
+                                //if ($obj->public) $labeltoshow.=' ('.$langs->trans("Public").')';
452
+                                //else $labeltoshow.=' ('.$langs->trans("Private").')';
453
+                                $resultat.='>';
454
+                                $resultat.=$labeltoshow;
455
+                                $resultat.='</option>';
456
+                            }
457
+                            $out.= $resultat;
458
+                        }
459
+                    }
460
+                    $i++;
461
+                }
462
+            }
463
+            if (empty($option_only)) {
464
+                $out.= '</select>';
465
+            }
466
+
467
+            print $out;
468
+
469
+            $this->db->free($resql);
470
+            return $num;
471
+        }
472
+        else
473
+        {
474
+            dol_print_error($this->db);
475
+            return -1;
476
+        }
477
+    }
478 478
 
479 479
 
480 480
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
481
-	/**
482
-	 *    Build a HTML select list of element of same thirdparty to suggest to link them to project
483
-	 *
484
-	 *    @param	string		$table_element		Table of the element to update
485
-	 *    @param	string		$socid				If of thirdparty to use as filter or 'id1,id2,...'
486
-	 *    @param	string		$morecss			More CSS
487
-	 *    @param    int         $limitonstatus      Add filters to limit length of list to opened status (for example to avoid ERR_RESPONSE_HEADERS_TOO_BIG on project/element.php page). TODO To implement
488
-	 *    @param	string		$projectkey			Equivalent key  to fk_projet for actual table_element
489
-	 *    @return	int|string						The HTML select list of element or '' if nothing or -1 if KO
490
-	 */
491
-	function select_element($table_element, $socid=0, $morecss='', $limitonstatus=-2,$projectkey="fk_projet")
492
-	{
481
+    /**
482
+     *    Build a HTML select list of element of same thirdparty to suggest to link them to project
483
+     *
484
+     *    @param	string		$table_element		Table of the element to update
485
+     *    @param	string		$socid				If of thirdparty to use as filter or 'id1,id2,...'
486
+     *    @param	string		$morecss			More CSS
487
+     *    @param    int         $limitonstatus      Add filters to limit length of list to opened status (for example to avoid ERR_RESPONSE_HEADERS_TOO_BIG on project/element.php page). TODO To implement
488
+     *    @param	string		$projectkey			Equivalent key  to fk_projet for actual table_element
489
+     *    @return	int|string						The HTML select list of element or '' if nothing or -1 if KO
490
+     */
491
+    function select_element($table_element, $socid=0, $morecss='', $limitonstatus=-2,$projectkey="fk_projet")
492
+    {
493 493
         // phpcs:enable
494
-		global $conf, $langs;
495
-
496
-		if ($table_element == 'projet_task') return '';		// Special cas of element we never link to a project (already always done)
497
-
498
-		$linkedtothirdparty=false;
499
-		if (! in_array($table_element, array('don','expensereport_det','expensereport','loan','stock_mouvement','payment_salary','payment_various','chargesociales'))) $linkedtothirdparty=true;
500
-
501
-		$sqlfilter='';
502
-
503
-		//print $table_element;
504
-		switch ($table_element)
505
-		{
506
-			case "loan":
507
-				$sql = "SELECT t.rowid, t.label as ref";
508
-				break;
509
-			case "facture":
510
-				$sql = "SELECT t.rowid, t.ref as ref";
511
-				break;
512
-			case "facture_fourn":
513
-				$sql = "SELECT t.rowid, t.ref, t.ref_supplier";
514
-				break;
515
-			case "commande_fourn":
516
-			case "commande_fournisseur":
517
-			    $sql = "SELECT t.rowid, t.ref, t.ref_supplier";
518
-				break;
519
-			case "facture_rec":
520
-				$sql = "SELECT t.rowid, t.titre as ref";
521
-				break;
522
-			case "actioncomm":
523
-				$sql = "SELECT t.id as rowid, t.label as ref";
524
-				$projectkey="fk_project";
525
-				break;
526
-			case "expensereport":
527
-				return '';
528
-			case "expensereport_det":
529
-				/*$sql = "SELECT rowid, '' as ref";	// table is llx_expensereport_det
494
+        global $conf, $langs;
495
+
496
+        if ($table_element == 'projet_task') return '';		// Special cas of element we never link to a project (already always done)
497
+
498
+        $linkedtothirdparty=false;
499
+        if (! in_array($table_element, array('don','expensereport_det','expensereport','loan','stock_mouvement','payment_salary','payment_various','chargesociales'))) $linkedtothirdparty=true;
500
+
501
+        $sqlfilter='';
502
+
503
+        //print $table_element;
504
+        switch ($table_element)
505
+        {
506
+            case "loan":
507
+                $sql = "SELECT t.rowid, t.label as ref";
508
+                break;
509
+            case "facture":
510
+                $sql = "SELECT t.rowid, t.ref as ref";
511
+                break;
512
+            case "facture_fourn":
513
+                $sql = "SELECT t.rowid, t.ref, t.ref_supplier";
514
+                break;
515
+            case "commande_fourn":
516
+            case "commande_fournisseur":
517
+                $sql = "SELECT t.rowid, t.ref, t.ref_supplier";
518
+                break;
519
+            case "facture_rec":
520
+                $sql = "SELECT t.rowid, t.titre as ref";
521
+                break;
522
+            case "actioncomm":
523
+                $sql = "SELECT t.id as rowid, t.label as ref";
524
+                $projectkey="fk_project";
525
+                break;
526
+            case "expensereport":
527
+                return '';
528
+            case "expensereport_det":
529
+                /*$sql = "SELECT rowid, '' as ref";	// table is llx_expensereport_det
530 530
 				$projectkey="fk_projet";
531 531
 				break;*/
532
-				return '';
533
-			case "commande":
534
-		    case "contrat":
535
-			case "fichinter":
536
-			    $sql = "SELECT t.rowid, t.ref";
537
-			    break;
538
-			case 'stock_mouvement':
539
-				$sql = 'SELECT t.rowid, t.label as ref';
540
-				$projectkey='fk_origin';
541
-				break;
542
-			case "payment_salary":
543
-				$sql = "SELECT t.rowid, t.num_payment as ref";	// TODO In a future fill and use real ref field
544
-				break;
545
-			case "payment_various":
546
-				$sql = "SELECT t.rowid, t.num_payment as ref";
547
-				break;
548
-			case "chargesociales":
549
-			default:
550
-				$sql = "SELECT t.rowid, t.ref";
551
-				break;
552
-		}
553
-		if ($linkedtothirdparty) $sql.=", s.nom as name";
554
-		$sql.= " FROM ".MAIN_DB_PREFIX.$table_element." as t";
555
-		if ($linkedtothirdparty) $sql.=", ".MAIN_DB_PREFIX."societe as s";
556
-		$sql.= " WHERE ".$projectkey." is null";
557
-		if (! empty($socid) && $linkedtothirdparty)
558
-		{
559
-		    if (is_numeric($socid)) $sql.= " AND t.fk_soc=".$socid;
560
-		    else $sql.= " AND t.fk_soc IN (".$socid.")";
561
-		}
562
-		if (! in_array($table_element, array('expensereport_det','stock_mouvement'))) $sql.= ' AND t.entity IN ('.getEntity('project').')';
563
-		if ($linkedtothirdparty) $sql.=" AND s.rowid = t.fk_soc";
564
-		if ($sqlfilter) $sql.= " AND ".$sqlfilter;
565
-		$sql.= " ORDER BY ref DESC";
566
-
567
-		dol_syslog(get_class($this).'::select_element', LOG_DEBUG);
568
-		$resql=$this->db->query($sql);
569
-		if ($resql)
570
-		{
571
-			$num = $this->db->num_rows($resql);
572
-			$i = 0;
573
-			if ($num > 0)
574
-			{
575
-				$sellist = '<select class="flat elementselect css'.$table_element.($morecss?' '.$morecss:'').'" name="elementselect">';
576
-				$sellist .='<option value="-1"></option>';
577
-				while ($i < $num)
578
-				{
579
-					$obj = $this->db->fetch_object($resql);
580
-					$ref=$obj->ref?$obj->ref:$obj->rowid;
581
-					if (! empty($obj->ref_supplier)) $ref.=' ('.$obj->ref_supplier.')';
582
-					if (! empty($obj->name)) $ref.=' - '.$obj->name;
583
-					$sellist .='<option value="'.$obj->rowid.'">'.$ref.'</option>';
584
-					$i++;
585
-				}
586
-				$sellist .='</select>';
587
-			}
588
-			/*else
532
+                return '';
533
+            case "commande":
534
+            case "contrat":
535
+            case "fichinter":
536
+                $sql = "SELECT t.rowid, t.ref";
537
+                break;
538
+            case 'stock_mouvement':
539
+                $sql = 'SELECT t.rowid, t.label as ref';
540
+                $projectkey='fk_origin';
541
+                break;
542
+            case "payment_salary":
543
+                $sql = "SELECT t.rowid, t.num_payment as ref";	// TODO In a future fill and use real ref field
544
+                break;
545
+            case "payment_various":
546
+                $sql = "SELECT t.rowid, t.num_payment as ref";
547
+                break;
548
+            case "chargesociales":
549
+            default:
550
+                $sql = "SELECT t.rowid, t.ref";
551
+                break;
552
+        }
553
+        if ($linkedtothirdparty) $sql.=", s.nom as name";
554
+        $sql.= " FROM ".MAIN_DB_PREFIX.$table_element." as t";
555
+        if ($linkedtothirdparty) $sql.=", ".MAIN_DB_PREFIX."societe as s";
556
+        $sql.= " WHERE ".$projectkey." is null";
557
+        if (! empty($socid) && $linkedtothirdparty)
558
+        {
559
+            if (is_numeric($socid)) $sql.= " AND t.fk_soc=".$socid;
560
+            else $sql.= " AND t.fk_soc IN (".$socid.")";
561
+        }
562
+        if (! in_array($table_element, array('expensereport_det','stock_mouvement'))) $sql.= ' AND t.entity IN ('.getEntity('project').')';
563
+        if ($linkedtothirdparty) $sql.=" AND s.rowid = t.fk_soc";
564
+        if ($sqlfilter) $sql.= " AND ".$sqlfilter;
565
+        $sql.= " ORDER BY ref DESC";
566
+
567
+        dol_syslog(get_class($this).'::select_element', LOG_DEBUG);
568
+        $resql=$this->db->query($sql);
569
+        if ($resql)
570
+        {
571
+            $num = $this->db->num_rows($resql);
572
+            $i = 0;
573
+            if ($num > 0)
574
+            {
575
+                $sellist = '<select class="flat elementselect css'.$table_element.($morecss?' '.$morecss:'').'" name="elementselect">';
576
+                $sellist .='<option value="-1"></option>';
577
+                while ($i < $num)
578
+                {
579
+                    $obj = $this->db->fetch_object($resql);
580
+                    $ref=$obj->ref?$obj->ref:$obj->rowid;
581
+                    if (! empty($obj->ref_supplier)) $ref.=' ('.$obj->ref_supplier.')';
582
+                    if (! empty($obj->name)) $ref.=' - '.$obj->name;
583
+                    $sellist .='<option value="'.$obj->rowid.'">'.$ref.'</option>';
584
+                    $i++;
585
+                }
586
+                $sellist .='</select>';
587
+            }
588
+            /*else
589 589
 			{
590 590
 				$sellist = '<select class="flat" name="elementselect">';
591 591
 				$sellist.= '<option value="0" disabled>'.$langs->trans("None").'</option>';
592 592
 				$sellist.= '</select>';
593 593
 			}*/
594
-			$this->db->free($resql);
595
-
596
-			return $sellist;
597
-		}
598
-		else
599
-		{
600
-			dol_print_error($this->db);
601
-			$this->error=$this->db->lasterror();
602
-			$this->errors[]=$this->db->lasterror();
603
-			dol_syslog(get_class($this) . "::select_element " . $this->error, LOG_ERR);
604
-			return -1;
605
-		}
606
-	}
607
-
608
-
609
-	/**
610
-	 *    Build a HTML select list of element of same thirdparty to suggest to link them to project
611
-	 *
612
-	 *    @param   string      $htmlname           HTML name
613
-	 *    @param   string      $preselected        Preselected (int or 'all' or 'none')
614
-	 *    @param   int         $showempty          Add an empty line
615
-	 *    @param   int         $useshortlabel      Use short label
616
-	 *    @param   int         $showallnone        Add choice "All" and "None"
617
-	 *    @param   int         $showpercent        Show default probability for status
618
-	 *    @param   string      $morecss            Add more css
619
-	 *    @return  int|string                      The HTML select list of element or '' if nothing or -1 if KO
620
-	 */
621
-	function selectOpportunityStatus($htmlname, $preselected='-1', $showempty=1, $useshortlabel=0, $showallnone=0, $showpercent=0, $morecss='')
622
-	{
623
-		global $conf, $langs;
624
-
625
-		$sql = "SELECT rowid, code, label, percent";
626
-		$sql.= " FROM ".MAIN_DB_PREFIX.'c_lead_status';
627
-		$sql.= " WHERE active = 1";
628
-		$sql.= " ORDER BY position";
629
-
630
-		$resql=$this->db->query($sql);
631
-		if ($resql)
632
-		{
633
-			$num = $this->db->num_rows($resql);
634
-			$i = 0;
635
-			if ($num > 0)
636
-			{
637
-				$sellist = '<select class="flat oppstatus'.($morecss?' '.$morecss:'').'" id="'.$htmlname.'" name="'.$htmlname.'">';
638
-				if ($showempty) {
594
+            $this->db->free($resql);
595
+
596
+            return $sellist;
597
+        }
598
+        else
599
+        {
600
+            dol_print_error($this->db);
601
+            $this->error=$this->db->lasterror();
602
+            $this->errors[]=$this->db->lasterror();
603
+            dol_syslog(get_class($this) . "::select_element " . $this->error, LOG_ERR);
604
+            return -1;
605
+        }
606
+    }
607
+
608
+
609
+    /**
610
+     *    Build a HTML select list of element of same thirdparty to suggest to link them to project
611
+     *
612
+     *    @param   string      $htmlname           HTML name
613
+     *    @param   string      $preselected        Preselected (int or 'all' or 'none')
614
+     *    @param   int         $showempty          Add an empty line
615
+     *    @param   int         $useshortlabel      Use short label
616
+     *    @param   int         $showallnone        Add choice "All" and "None"
617
+     *    @param   int         $showpercent        Show default probability for status
618
+     *    @param   string      $morecss            Add more css
619
+     *    @return  int|string                      The HTML select list of element or '' if nothing or -1 if KO
620
+     */
621
+    function selectOpportunityStatus($htmlname, $preselected='-1', $showempty=1, $useshortlabel=0, $showallnone=0, $showpercent=0, $morecss='')
622
+    {
623
+        global $conf, $langs;
624
+
625
+        $sql = "SELECT rowid, code, label, percent";
626
+        $sql.= " FROM ".MAIN_DB_PREFIX.'c_lead_status';
627
+        $sql.= " WHERE active = 1";
628
+        $sql.= " ORDER BY position";
629
+
630
+        $resql=$this->db->query($sql);
631
+        if ($resql)
632
+        {
633
+            $num = $this->db->num_rows($resql);
634
+            $i = 0;
635
+            if ($num > 0)
636
+            {
637
+                $sellist = '<select class="flat oppstatus'.($morecss?' '.$morecss:'').'" id="'.$htmlname.'" name="'.$htmlname.'">';
638
+                if ($showempty) {
639 639
                     // Without &nbsp, strange move of screen when switching value
640 640
                     $sellist.= '<option value="-1">&nbsp;</option>';
641 641
                 }
642
-				if ($showallnone) {
642
+                if ($showallnone) {
643 643
                     $sellist.= '<option value="all"'.($preselected == 'all'?' selected="selected"':'').'>-- '.$langs->trans("OnlyOpportunitiesShort").' --</option>';
644
-				    $sellist.= '<option value="openedopp"'.($preselected == 'openedopp'?' selected="selected"':'').'>-- '.$langs->trans("OpenedOpportunitiesShort").' --</option>';
645
-				    $sellist.= '<option value="notopenedopp"'.($preselected == 'notopenedopp'?' selected="selected"':'').'>-- '.$langs->trans("NotOpenedOpportunitiesShort").' --</option>';
646
-				    $sellist.= '<option value="none"'.($preselected == 'none'?' selected="selected"':'').'>-- '.$langs->trans("NotAnOpportunityShort").' --</option>';
644
+                    $sellist.= '<option value="openedopp"'.($preselected == 'openedopp'?' selected="selected"':'').'>-- '.$langs->trans("OpenedOpportunitiesShort").' --</option>';
645
+                    $sellist.= '<option value="notopenedopp"'.($preselected == 'notopenedopp'?' selected="selected"':'').'>-- '.$langs->trans("NotOpenedOpportunitiesShort").' --</option>';
646
+                    $sellist.= '<option value="none"'.($preselected == 'none'?' selected="selected"':'').'>-- '.$langs->trans("NotAnOpportunityShort").' --</option>';
647
+                }
648
+                while ($i < $num)
649
+                {
650
+                    $obj = $this->db->fetch_object($resql);
651
+
652
+                    $sellist .='<option value="'.$obj->rowid.'" defaultpercent="'.$obj->percent.'" elemcode="'.$obj->code.'"';
653
+                    if ($obj->rowid == $preselected) $sellist .= ' selected="selected"';
654
+                    $sellist .= '>';
655
+                    if ($useshortlabel)
656
+                    {
657
+                        $finallabel = ($langs->transnoentitiesnoconv("OppStatus".$obj->code) != "OppStatus".$obj->code ? $langs->transnoentitiesnoconv("OppStatus".$obj->code) : $obj->label);
658
+                    }
659
+                    else
660
+                    {
661
+                        $finallabel = ($langs->transnoentitiesnoconv("OppStatus".$obj->code) != "OppStatus".$obj->code ? $langs->transnoentitiesnoconv("OppStatus".$obj->code) : $obj->label);
662
+                        if ($showpercent) $finallabel.= ' ('.$obj->percent.'%)';
663
+                    }
664
+                    $sellist .= $finallabel;
665
+                    $sellist .='</option>';
666
+                    $i++;
647 667
                 }
648
-				while ($i < $num)
649
-				{
650
-					$obj = $this->db->fetch_object($resql);
651
-
652
-					$sellist .='<option value="'.$obj->rowid.'" defaultpercent="'.$obj->percent.'" elemcode="'.$obj->code.'"';
653
-					if ($obj->rowid == $preselected) $sellist .= ' selected="selected"';
654
-					$sellist .= '>';
655
-					if ($useshortlabel)
656
-					{
657
-						$finallabel = ($langs->transnoentitiesnoconv("OppStatus".$obj->code) != "OppStatus".$obj->code ? $langs->transnoentitiesnoconv("OppStatus".$obj->code) : $obj->label);
658
-					}
659
-					else
660
-					{
661
-						$finallabel = ($langs->transnoentitiesnoconv("OppStatus".$obj->code) != "OppStatus".$obj->code ? $langs->transnoentitiesnoconv("OppStatus".$obj->code) : $obj->label);
662
-						if ($showpercent) $finallabel.= ' ('.$obj->percent.'%)';
663
-					}
664
-					$sellist .= $finallabel;
665
-					$sellist .='</option>';
666
-					$i++;
667
-				}
668
-				$sellist .='</select>';
669
-			}
670
-			/*else
668
+                $sellist .='</select>';
669
+            }
670
+            /*else
671 671
 			{
672 672
 				$sellist = '<select class="flat" name="elementselect">';
673 673
 				$sellist.= '<option value="0" disabled>'.$langs->trans("None").'</option>';
674 674
 				$sellist.= '</select>';
675 675
 			}*/
676
-			$this->db->free($resql);
677
-
678
-			return $sellist;
679
-		}
680
-		else
681
-		{
682
-			$this->error=$this->db->lasterror();
683
-			$this->errors[]=$this->db->lasterror();
684
-			dol_syslog(get_class($this) . "::selectOpportunityStatus " . $this->error, LOG_ERR);
685
-			return -1;
686
-		}
687
-	}
676
+            $this->db->free($resql);
677
+
678
+            return $sellist;
679
+        }
680
+        else
681
+        {
682
+            $this->error=$this->db->lasterror();
683
+            $this->errors[]=$this->db->lasterror();
684
+            dol_syslog(get_class($this) . "::selectOpportunityStatus " . $this->error, LOG_ERR);
685
+            return -1;
686
+        }
687
+    }
688 688
 }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/html.formother.class.php 1 patch
Indentation   +146 added lines, -146 removed lines patch added patch discarded remove patch
@@ -40,9 +40,9 @@  discard block
 block discarded – undo
40 40
     private $db;
41 41
 
42 42
     /**
43
-	 * @var string Error code (or message)
44
-	 */
45
-	public $error;
43
+     * @var string Error code (or message)
44
+     */
45
+    public $error;
46 46
 
47 47
 
48 48
     /**
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
         $sql = "SELECT rowid, label";
74 74
         $sql.= " FROM ".MAIN_DB_PREFIX."export_model";
75 75
         $sql.= " WHERE type = '".$type."'";
76
-		if (!empty($fk_user)) $sql.=" AND fk_user=".$fk_user;
76
+        if (!empty($fk_user)) $sql.=" AND fk_user=".$fk_user;
77 77
         $sql.= " ORDER BY rowid";
78 78
         $result = $this->db->query($sql);
79 79
         if ($result)
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
         $sql.= " WHERE e.active = 1 AND e.fk_pays = c.rowid";
180 180
         $sql.= " ORDER BY country, e.organization ASC, e.code ASC";
181 181
 
182
-    	dol_syslog(get_class($this).'::select_ecotaxes', LOG_DEBUG);
182
+        dol_syslog(get_class($this).'::select_ecotaxes', LOG_DEBUG);
183 183
         $resql=$this->db->query($sql);
184 184
         if ($resql)
185 185
         {
@@ -230,50 +230,50 @@  discard block
 block discarded – undo
230 230
     function select_revenue_stamp($selected='', $htmlname='revenuestamp', $country_code='')
231 231
     {
232 232
         // phpcs:enable
233
-    	global $langs;
234
-
235
-    	$out='';
236
-
237
-    	$sql = "SELECT r.taux, r.revenuestamp_type";
238
-    	$sql.= " FROM ".MAIN_DB_PREFIX."c_revenuestamp as r,".MAIN_DB_PREFIX."c_country as c";
239
-    	$sql.= " WHERE r.active = 1 AND r.fk_pays = c.rowid";
240
-    	$sql.= " AND c.code = '".$country_code."'";
241
-
242
-    	dol_syslog(get_class($this).'::select_revenue_stamp', LOG_DEBUG);
243
-    	$resql=$this->db->query($sql);
244
-    	if ($resql)
245
-    	{
246
-    		$out.='<select class="flat" name="'.$htmlname.'">';
247
-    		$num = $this->db->num_rows($resql);
248
-    		$i = 0;
249
-    		$out.='<option value="0">&nbsp;</option>'."\n";
250
-    		if ($num)
251
-    		{
252
-    			while ($i < $num)
253
-    			{
254
-    				$obj = $this->db->fetch_object($resql);
255
-    				if (($selected && $selected == $obj->taux) || $num == 1)
256
-    				{
257
-    					$out.='<option value="'.$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '').'"'.($obj->revenuestamp_type == 'percent' ? ' data-type="percent"' : '').' selected>';
258
-    				}
259
-    				else
260
-    				{
261
-    					$out.='<option value="'.$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '').'"'.($obj->revenuestamp_type == 'percent' ? ' data-type="percent"' : '').'>';
262
-    					//print '<option onmouseover="showtip(\''.$obj->libelle.'\')" onMouseout="hidetip()" value="'.$obj->rowid.'">';
263
-    				}
264
-    				$out.=$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '');
265
-    				$out.='</option>';
266
-    				$i++;
267
-    			}
268
-    		}
269
-    		$out.='</select>';
270
-    		return $out;
271
-    	}
272
-    	else
273
-    	{
274
-    		dol_print_error($this->db);
275
-    		return '';
276
-    	}
233
+        global $langs;
234
+
235
+        $out='';
236
+
237
+        $sql = "SELECT r.taux, r.revenuestamp_type";
238
+        $sql.= " FROM ".MAIN_DB_PREFIX."c_revenuestamp as r,".MAIN_DB_PREFIX."c_country as c";
239
+        $sql.= " WHERE r.active = 1 AND r.fk_pays = c.rowid";
240
+        $sql.= " AND c.code = '".$country_code."'";
241
+
242
+        dol_syslog(get_class($this).'::select_revenue_stamp', LOG_DEBUG);
243
+        $resql=$this->db->query($sql);
244
+        if ($resql)
245
+        {
246
+            $out.='<select class="flat" name="'.$htmlname.'">';
247
+            $num = $this->db->num_rows($resql);
248
+            $i = 0;
249
+            $out.='<option value="0">&nbsp;</option>'."\n";
250
+            if ($num)
251
+            {
252
+                while ($i < $num)
253
+                {
254
+                    $obj = $this->db->fetch_object($resql);
255
+                    if (($selected && $selected == $obj->taux) || $num == 1)
256
+                    {
257
+                        $out.='<option value="'.$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '').'"'.($obj->revenuestamp_type == 'percent' ? ' data-type="percent"' : '').' selected>';
258
+                    }
259
+                    else
260
+                    {
261
+                        $out.='<option value="'.$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '').'"'.($obj->revenuestamp_type == 'percent' ? ' data-type="percent"' : '').'>';
262
+                        //print '<option onmouseover="showtip(\''.$obj->libelle.'\')" onMouseout="hidetip()" value="'.$obj->rowid.'">';
263
+                    }
264
+                    $out.=$obj->taux.($obj->revenuestamp_type == 'percent' ? '%' : '');
265
+                    $out.='</option>';
266
+                    $i++;
267
+                }
268
+            }
269
+            $out.='</select>';
270
+            return $out;
271
+        }
272
+        else
273
+        {
274
+            dol_print_error($this->db);
275
+            return '';
276
+        }
277 277
     }
278 278
 
279 279
 
@@ -368,8 +368,8 @@  discard block
 block discarded – undo
368 368
         }
369 369
         if ($nocateg)
370 370
         {
371
-        	$langs->load("categories");
372
-        	$moreforfilter.='<option value="-2"'.($selected == -2 ? ' selected':'').'>- '.$langs->trans("NotCategorized").' -</option>';
371
+            $langs->load("categories");
372
+            $moreforfilter.='<option value="-2"'.($selected == -2 ? ' selected':'').'>- '.$langs->trans("NotCategorized").' -</option>';
373 373
         }
374 374
         $moreforfilter.='</select>';
375 375
 
@@ -404,7 +404,7 @@  discard block
 block discarded – undo
404 404
             $comboenhancement = ajax_combobox($htmlname);
405 405
             if ($comboenhancement)
406 406
             {
407
-            	$out.=$comboenhancement;
407
+                $out.=$comboenhancement;
408 408
             }
409 409
         }
410 410
         // Select each sales and print them in a select input
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
             $sql_usr.= " WHERE u2.entity IN (0,".$conf->entity.")";
427 427
             $sql_usr.= " AND u2.rowid = sc.fk_user AND sc.fk_soc=".$user->societe_id;
428 428
         }
429
-	    $sql_usr.= " ORDER BY statut DESC, lastname ASC";  // Do not use 'ORDER BY u.statut' here, not compatible with the UNION.
429
+        $sql_usr.= " ORDER BY statut DESC, lastname ASC";  // Do not use 'ORDER BY u.statut' here, not compatible with the UNION.
430 430
         //print $sql_usr;exit;
431 431
 
432 432
         $resql_usr = $this->db->query($sql_usr);
@@ -450,18 +450,18 @@  discard block
 block discarded – undo
450 450
                 }
451 451
                 if ($showstatus >= 0)
452 452
                 {
453
-					if ($obj_usr->statut == 1 && $showstatus == 1)
454
-					{
455
-						$out.=($moreinfo?' - ':' (').$langs->trans('Enabled');
456
-	                	$moreinfo++;
457
-					}
458
-					if ($obj_usr->statut == 0)
459
-					{
460
-						$out.=($moreinfo?' - ':' (').$langs->trans('Disabled');
461
-                		$moreinfo++;
462
-					}
463
-				}
464
-				$out.=($moreinfo?')':'');
453
+                    if ($obj_usr->statut == 1 && $showstatus == 1)
454
+                    {
455
+                        $out.=($moreinfo?' - ':' (').$langs->trans('Enabled');
456
+                        $moreinfo++;
457
+                    }
458
+                    if ($obj_usr->statut == 0)
459
+                    {
460
+                        $out.=($moreinfo?' - ':' (').$langs->trans('Disabled');
461
+                        $moreinfo++;
462
+                    }
463
+                }
464
+                $out.=($moreinfo?')':'');
465 465
                 $out.='</option>';
466 466
             }
467 467
             $this->db->free($resql_usr);
@@ -486,7 +486,7 @@  discard block
 block discarded – undo
486 486
      * 	@param	int		$mode					0=Return list of tasks and their projects, 1=Return projects and tasks if exists
487 487
      *  @param  int		$useempty       		0=Allow empty values
488 488
      *  @param	int		$disablechildoftaskid	1=Disable task that are child of the provided task id
489
-	 *  @param	string	$filteronprojstatus		Filter on project status ('-1'=no filter, '0,1'=Draft+Validated status)
489
+     *  @param	string	$filteronprojstatus		Filter on project status ('-1'=no filter, '0,1'=Draft+Validated status)
490 490
      *  @param	string	$morecss				More css
491 491
      *  @return	void
492 492
      */
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
         $tasksarray=$task->getTasksArray($modetask?$user:0, $modeproject?$user:0, $projectid, 0, $mode, '', $filteronprojstatus);
502 502
         if ($tasksarray)
503 503
         {
504
-        	print '<select class="flat'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'">';
504
+            print '<select class="flat'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'">';
505 505
             if ($useempty) print '<option value="0">&nbsp;</option>';
506 506
             $j=0;
507 507
             $level=0;
@@ -537,11 +537,11 @@  discard block
 block discarded – undo
537 537
         $numlines=count($lines);
538 538
         for ($i = 0 ; $i < $numlines ; $i++)
539 539
         {
540
-        	if ($lines[$i]->fk_parent == $parent)
540
+            if ($lines[$i]->fk_parent == $parent)
541 541
             {
542 542
                 $var = !$var;
543 543
 
544
-				//var_dump($selectedproject."--".$selectedtask."--".$lines[$i]->fk_project."_".$lines[$i]->id);		// $lines[$i]->id may be empty if project has no lines
544
+                //var_dump($selectedproject."--".$selectedtask."--".$lines[$i]->fk_project."_".$lines[$i]->id);		// $lines[$i]->id may be empty if project has no lines
545 545
 
546 546
                 // Break on a new project
547 547
                 if ($parent == 0)	// We are on a task at first level
@@ -574,13 +574,13 @@  discard block
 block discarded – undo
574 574
                 // Print task
575 575
                 if (isset($lines[$i]->id))		// We use isset because $lines[$i]->id may be null if project has no task and are on root project (tasks may be caught by a left join). We enter here only if '0' or >0
576 576
                 {
577
-                	// Check if we must disable entry
578
-                	$disabled=0;
579
-                	if ($disablechildoftaskid && (($lines[$i]->id == $disablechildoftaskid || $lines[$i]->fk_parent == $disablechildoftaskid)))
580
-                	{
581
-               			$disabled++;
582
-               			if ($lines[$i]->fk_parent == $disablechildoftaskid) $newdisablechildoftaskid=$lines[$i]->id;	// If task is child of a disabled parent, we will propagate id to disable next child too
583
-                	}
577
+                    // Check if we must disable entry
578
+                    $disabled=0;
579
+                    if ($disablechildoftaskid && (($lines[$i]->id == $disablechildoftaskid || $lines[$i]->fk_parent == $disablechildoftaskid)))
580
+                    {
581
+                            $disabled++;
582
+                            if ($lines[$i]->fk_parent == $disablechildoftaskid) $newdisablechildoftaskid=$lines[$i]->id;	// If task is child of a disabled parent, we will propagate id to disable next child too
583
+                    }
584 584
 
585 585
                     print '<option value="'.$lines[$i]->fk_project.'_'.$lines[$i]->id.'"';
586 586
                     if (($lines[$i]->id == $selectedtask) || ($lines[$i]->fk_project.'_'.$lines[$i]->id == $selectedtask)) print ' selected';
@@ -623,14 +623,14 @@  discard block
 block discarded – undo
623 623
      */
624 624
     static function showColor($color, $textifnotdefined='')
625 625
     {
626
-    	$textcolor='FFF';
627
-    	include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
628
-    	if(colorIsLight($color)) $textcolor='000';
626
+        $textcolor='FFF';
627
+        include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
628
+        if(colorIsLight($color)) $textcolor='000';
629 629
 
630
-    	$color = colorArrayToHex(colorStringToArray($color,array()),'');
630
+        $color = colorArrayToHex(colorStringToArray($color,array()),'');
631 631
 
632
-		if ($color) print '<input type="text" class="colorthumb" disabled style="padding: 1px; margin-top: 0; margin-bottom: 0; color: #'.$textcolor.'; background-color: #'.$color.'" value="'.$color.'">';
633
-		else print $textifnotdefined;
632
+        if ($color) print '<input type="text" class="colorthumb" disabled style="padding: 1px; margin-top: 0; margin-bottom: 0; color: #'.$textcolor.'; background-color: #'.$color.'" value="'.$color.'">';
633
+        else print $textifnotdefined;
634 634
     }
635 635
 
636 636
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
@@ -649,7 +649,7 @@  discard block
 block discarded – undo
649 649
     function select_color($set_color='', $prefix='f_color', $form_name='', $showcolorbox=1, $arrayofcolors='')
650 650
     {
651 651
         // phpcs:enable
652
-    	print $this->selectColor($set_color, $prefix, $form_name, $showcolorbox, $arrayofcolors);
652
+        print $this->selectColor($set_color, $prefix, $form_name, $showcolorbox, $arrayofcolors);
653 653
     }
654 654
 
655 655
     /**
@@ -666,10 +666,10 @@  discard block
 block discarded – undo
666 666
      */
667 667
     static function selectColor($set_color='', $prefix='f_color', $form_name='', $showcolorbox=1, $arrayofcolors='', $morecss='')
668 668
     {
669
-	    // Deprecation warning
670
-	    if ($form_name) {
671
-		    dol_syslog(__METHOD__ . ": form_name parameter is deprecated", LOG_WARNING);
672
-	    }
669
+        // Deprecation warning
670
+        if ($form_name) {
671
+            dol_syslog(__METHOD__ . ": form_name parameter is deprecated", LOG_WARNING);
672
+        }
673 673
 
674 674
         global $langs,$conf;
675 675
 
@@ -680,9 +680,9 @@  discard block
 block discarded – undo
680 680
             $langs->load("other");
681 681
             if (empty($conf->dol_use_jmobile))
682 682
             {
683
-	            $out.= '<link rel="stylesheet" media="screen" type="text/css" href="'.DOL_URL_ROOT.'/includes/jquery/plugins/jpicker/css/jPicker-1.1.6.css" />';
684
-	            $out.= '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jpicker/jpicker-1.1.6.js"></script>';
685
-	            $out.= '<script type="text/javascript">
683
+                $out.= '<link rel="stylesheet" media="screen" type="text/css" href="'.DOL_URL_ROOT.'/includes/jquery/plugins/jpicker/css/jPicker-1.1.6.css" />';
684
+                $out.= '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/jpicker/jpicker-1.1.6.js"></script>';
685
+                $out.= '<script type="text/javascript">
686 686
 	             jQuery(document).ready(function(){
687 687
 	                $(\'#colorpicker'.$prefix.'\').jPicker( {
688 688
 	                window: {
@@ -726,9 +726,9 @@  discard block
 block discarded – undo
726 726
         {
727 727
             if (empty($conf->dol_use_jmobile))
728 728
             {
729
-	        	$out.= '<link rel="stylesheet" href="'.DOL_URL_ROOT.'/includes/jquery/plugins/colorpicker/jquery.colorpicker.css" type="text/css" media="screen" />';
730
-	            $out.= '<script src="'.DOL_URL_ROOT.'/includes/jquery/plugins/colorpicker/jquery.colorpicker.js" type="text/javascript"></script>';
731
-	            $out.= '<script type="text/javascript">
729
+                $out.= '<link rel="stylesheet" href="'.DOL_URL_ROOT.'/includes/jquery/plugins/colorpicker/jquery.colorpicker.css" type="text/css" media="screen" />';
730
+                $out.= '<script src="'.DOL_URL_ROOT.'/includes/jquery/plugins/colorpicker/jquery.colorpicker.js" type="text/javascript"></script>';
731
+                $out.= '<script type="text/javascript">
732 732
 	             jQuery(document).ready(function(){
733 733
 	                 jQuery(\'#colorpicker'.$prefix.'\').colorpicker({
734 734
 	                     size: 14,
@@ -929,7 +929,7 @@  discard block
 block discarded – undo
929 929
         $out.= '<select class="flat'.($morecss?' '.$morecss:'').'" id="' . $htmlname . '" name="' . $htmlname . '"'.$option.' >';
930 930
         if($useempty)
931 931
         {
932
-        	$selected_html='';
932
+            $selected_html='';
933 933
             if ($selected == '') $selected_html = ' selected';
934 934
             $out.= '<option value=""' . $selected_html . '>&nbsp;</option>';
935 935
         }
@@ -1028,55 +1028,55 @@  discard block
 block discarded – undo
1028 1028
         $boxidactivatedforuser=array();
1029 1029
         foreach($boxactivated as $box)
1030 1030
         {
1031
-        	if (empty($user->conf->$confuserzone) || $box->fk_user == $user->id) $boxidactivatedforuser[$box->id]=$box->id;	// We keep only boxes to show for user
1031
+            if (empty($user->conf->$confuserzone) || $box->fk_user == $user->id) $boxidactivatedforuser[$box->id]=$box->id;	// We keep only boxes to show for user
1032 1032
         }
1033 1033
 
1034 1034
         // Define selectboxlist
1035 1035
         $arrayboxtoactivatelabel=array();
1036 1036
         if (! empty($user->conf->$confuserzone))
1037 1037
         {
1038
-        	$boxorder='';
1039
-        	$langs->load("boxes");	// Load label of boxes
1040
-        	foreach($boxactivated as $box)
1041
-        	{
1042
-        		if (! empty($boxidactivatedforuser[$box->id])) continue;	// Already visible for user
1043
-        		$label=$langs->transnoentitiesnoconv($box->boxlabel);
1044
-        		//if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')';
1045
-        		if (preg_match('/graph/',$box->class) && $conf->browser->layout != 'phone')
1046
-        		{
1047
-        			$label=$label.' <span class="fa fa-bar-chart"></span>';
1048
-        		}
1049
-        		$arrayboxtoactivatelabel[$box->id]=$label;			// We keep only boxes not shown for user, to show into combo list
1050
-        	}
1038
+            $boxorder='';
1039
+            $langs->load("boxes");	// Load label of boxes
1040
+            foreach($boxactivated as $box)
1041
+            {
1042
+                if (! empty($boxidactivatedforuser[$box->id])) continue;	// Already visible for user
1043
+                $label=$langs->transnoentitiesnoconv($box->boxlabel);
1044
+                //if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')';
1045
+                if (preg_match('/graph/',$box->class) && $conf->browser->layout != 'phone')
1046
+                {
1047
+                    $label=$label.' <span class="fa fa-bar-chart"></span>';
1048
+                }
1049
+                $arrayboxtoactivatelabel[$box->id]=$label;			// We keep only boxes not shown for user, to show into combo list
1050
+            }
1051 1051
             foreach($boxidactivatedforuser as $boxid)
1052
-        	{
1053
-       			if (empty($boxorder)) $boxorder.='A:';
1054
-  				$boxorder.=$boxid.',';
1055
-        	}
1056
-
1057
-        	//var_dump($boxidactivatedforuser);
1058
-
1059
-        	// Class Form must have been already loaded
1060
-        	$selectboxlist.='<!-- Form with select box list -->'."\n";
1061
-			$selectboxlist.='<form id="addbox" name="addbox" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1062
-			$selectboxlist.='<input type="hidden" name="addbox" value="addbox">';
1063
-			$selectboxlist.='<input type="hidden" name="userid" value="'.$user->id.'">';
1064
-			$selectboxlist.='<input type="hidden" name="areacode" value="'.$areacode.'">';
1065
-			$selectboxlist.='<input type="hidden" name="boxorder" value="'.$boxorder.'">';
1066
-			$selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected', 0, 1);
1052
+            {
1053
+                    if (empty($boxorder)) $boxorder.='A:';
1054
+                    $boxorder.=$boxid.',';
1055
+            }
1056
+
1057
+            //var_dump($boxidactivatedforuser);
1058
+
1059
+            // Class Form must have been already loaded
1060
+            $selectboxlist.='<!-- Form with select box list -->'."\n";
1061
+            $selectboxlist.='<form id="addbox" name="addbox" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1062
+            $selectboxlist.='<input type="hidden" name="addbox" value="addbox">';
1063
+            $selectboxlist.='<input type="hidden" name="userid" value="'.$user->id.'">';
1064
+            $selectboxlist.='<input type="hidden" name="areacode" value="'.$areacode.'">';
1065
+            $selectboxlist.='<input type="hidden" name="boxorder" value="'.$boxorder.'">';
1066
+            $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected', 0, 1);
1067 1067
             if (empty($conf->use_javascript_ajax)) $selectboxlist.=' <input type="submit" class="button" value="'.$langs->trans("AddBox").'">';
1068 1068
             $selectboxlist.='</form>';
1069 1069
             if (! empty($conf->use_javascript_ajax))
1070 1070
             {
1071
-            	include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1072
-            	$selectboxlist.=ajax_combobox("boxcombo");
1071
+                include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1072
+                $selectboxlist.=ajax_combobox("boxcombo");
1073 1073
             }
1074 1074
         }
1075 1075
 
1076 1076
         // Javascript code for dynamic actions
1077 1077
         if (! empty($conf->use_javascript_ajax))
1078 1078
         {
1079
-	        $selectboxlist.='<script type="text/javascript" language="javascript">
1079
+            $selectboxlist.='<script type="text/javascript" language="javascript">
1080 1080
 
1081 1081
 	        // To update list of activated boxes
1082 1082
 	        function updateBoxOrder(closing) {
@@ -1115,8 +1115,8 @@  discard block
 block discarded – undo
1115 1115
 	        			window.location.search=\'mainmenu='.GETPOST("mainmenu","aZ09").'&leftmenu='.GETPOST('leftmenu',"aZ09").'&action=addbox&boxid=\'+boxid;
1116 1116
 	                }
1117 1117
 	        	});';
1118
-	        	if (! count($arrayboxtoactivatelabel)) $selectboxlist.='jQuery("#boxcombo").hide();';
1119
-	        	$selectboxlist.='
1118
+                if (! count($arrayboxtoactivatelabel)) $selectboxlist.='jQuery("#boxcombo").hide();';
1119
+                $selectboxlist.='
1120 1120
 
1121 1121
 	        	jQuery("#boxhalfleft, #boxhalfright").sortable({
1122 1122
 	    	    	handle: \'.boxhandle\',
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
 
1142 1142
         	});'."\n";
1143 1143
 
1144
-	        $selectboxlist.='</script>'."\n";
1144
+            $selectboxlist.='</script>'."\n";
1145 1145
         }
1146 1146
 
1147 1147
         // Define boxlista and boxlistb
@@ -1149,10 +1149,10 @@  discard block
 block discarded – undo
1149 1149
 
1150 1150
         if ($nbboxactivated)
1151 1151
         {
1152
-        	// Load translation files required by the page
1152
+            // Load translation files required by the page
1153 1153
             $langs->loadLangs(array("boxes","projects"));
1154 1154
 
1155
-        	$emptybox=new ModeleBoxes($db);
1155
+            $emptybox=new ModeleBoxes($db);
1156 1156
 
1157 1157
             $boxlista.="\n<!-- Box left container -->\n";
1158 1158
 
@@ -1163,9 +1163,9 @@  discard block
 block discarded – undo
1163 1163
             $ii=0;
1164 1164
             foreach ($boxactivated as $key => $box)
1165 1165
             {
1166
-            	if ((! empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) continue;
1167
-				if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) $box->box_order='A'.sprintf("%02d",($ii+1));	// When box_order was not yet set to Axx or Bxx and is still 0
1168
-            	if (preg_match('/^A/i',$box->box_order)) // column A
1166
+                if ((! empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) continue;
1167
+                if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) $box->box_order='A'.sprintf("%02d",($ii+1));	// When box_order was not yet set to Axx or Bxx and is still 0
1168
+                if (preg_match('/^A/i',$box->box_order)) // column A
1169 1169
                 {
1170 1170
                     $ii++;
1171 1171
                     //print 'box_id '.$boxactivated[$ii]->box_id.' ';
@@ -1178,10 +1178,10 @@  discard block
 block discarded – undo
1178 1178
 
1179 1179
             if ($conf->browser->layout != 'phone')
1180 1180
             {
1181
-            	$emptybox->box_id='A';
1182
-            	$emptybox->info_box_head=array();
1183
-            	$emptybox->info_box_contents=array();
1184
-            	$boxlista.= $emptybox->outputBox(array(),array());
1181
+                $emptybox->box_id='A';
1182
+                $emptybox->info_box_head=array();
1183
+                $emptybox->info_box_contents=array();
1184
+                $boxlista.= $emptybox->outputBox(array(),array());
1185 1185
             }
1186 1186
             $boxlista.= "<!-- End box left container -->\n";
1187 1187
 
@@ -1190,9 +1190,9 @@  discard block
 block discarded – undo
1190 1190
             $ii=0;
1191 1191
             foreach ($boxactivated as $key => $box)
1192 1192
             {
1193
-            	if ((! empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) continue;
1194
-            	if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) $box->box_order='B'.sprintf("%02d",($ii+1));	// When box_order was not yet set to Axx or Bxx and is still 0
1195
-            	if (preg_match('/^B/i',$box->box_order)) // colonne B
1193
+                if ((! empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) continue;
1194
+                if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) $box->box_order='B'.sprintf("%02d",($ii+1));	// When box_order was not yet set to Axx or Bxx and is still 0
1195
+                if (preg_match('/^B/i',$box->box_order)) // colonne B
1196 1196
                 {
1197 1197
                     $ii++;
1198 1198
                     //print 'box_id '.$boxactivated[$ii]->box_id.' ';
@@ -1205,10 +1205,10 @@  discard block
 block discarded – undo
1205 1205
 
1206 1206
             if ($conf->browser->layout != 'phone')
1207 1207
             {
1208
-            	$emptybox->box_id='B';
1209
-            	$emptybox->info_box_head=array();
1210
-            	$emptybox->info_box_contents=array();
1211
-            	$boxlistb.= $emptybox->outputBox(array(),array());
1208
+                $emptybox->box_id='B';
1209
+                $emptybox->info_box_head=array();
1210
+                $emptybox->info_box_contents=array();
1211
+                $boxlistb.= $emptybox->outputBox(array(),array());
1212 1212
             }
1213 1213
 
1214 1214
             $boxlistb.= "<!-- End box right container -->\n";
@@ -1274,7 +1274,7 @@  discard block
 block discarded – undo
1274 1274
                 print "</select>";
1275 1275
             }
1276 1276
             else
1277
-			{
1277
+            {
1278 1278
                 print $langs->trans("DictionaryEmpty");
1279 1279
             }
1280 1280
         }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/notify.class.php 1 patch
Indentation   +750 added lines, -750 removed lines patch added patch discarded remove patch
@@ -31,766 +31,766 @@
 block discarded – undo
31 31
  */
32 32
 class Notify
33 33
 {
34
-	/**
35
-	 * @var int ID
36
-	 */
37
-	public $id;
34
+    /**
35
+     * @var int ID
36
+     */
37
+    public $id;
38 38
 
39
-	/**
39
+    /**
40 40
      * @var DoliDB Database handler.
41 41
      */
42 42
     public $db;
43 43
 
44
-	/**
45
-	 * @var string Error code (or message)
46
-	 */
47
-	public $error='';
44
+    /**
45
+     * @var string Error code (or message)
46
+     */
47
+    public $error='';
48 48
 
49
-	/**
50
-	 * @var string[] Error codes (or messages)
51
-	 */
52
-	public $errors = array();
49
+    /**
50
+     * @var string[] Error codes (or messages)
51
+     */
52
+    public $errors = array();
53 53
 
54
-	public $author;
55
-	public $ref;
56
-	public $date;
57
-	public $duree;
58
-	public $note;
54
+    public $author;
55
+    public $ref;
56
+    public $date;
57
+    public $duree;
58
+    public $note;
59 59
 
60
-	/**
60
+    /**
61 61
      * @var int Project ID
62 62
      */
63 63
     public $fk_project;
64 64
 
65
-	// Les codes actions sont definis dans la table llx_notify_def
66
-
67
-	// codes actions supported are
68
-	// @TODO defined also into interface_50_modNotificiation_Notificiation.class.php
69
-	public $arrayofnotifsupported = array(
70
-		'BILL_VALIDATE',
71
-		'BILL_PAYED',
72
-		'ORDER_VALIDATE',
73
-		'PROPAL_VALIDATE',
74
-		'PROPAL_CLOSE_SIGNED',
75
-		'FICHINTER_VALIDATE',
76
-		'FICHINTER_ADD_CONTACT',
77
-		'ORDER_SUPPLIER_VALIDATE',
78
-		'ORDER_SUPPLIER_APPROVE',
79
-		'ORDER_SUPPLIER_REFUSE',
80
-		'SHIPPING_VALIDATE',
81
-		'EXPENSE_REPORT_VALIDATE',
82
-		'EXPENSE_REPORT_APPROVE',
83
-		'HOLIDAY_VALIDATE',
84
-		'HOLIDAY_APPROVE'
85
-	);
86
-
87
-
88
-	/**
89
-	 *	Constructor
90
-	 *
91
-	 *	@param 		DoliDB		$db		Database handler
92
-	 */
93
-	function __construct($db)
94
-	{
95
-		$this->db = $db;
96
-	}
97
-
98
-
99
-	/**
100
-	 *  Return message that say how many notification (and to which email) will occurs on requested event.
101
-	 *	This is to show confirmation messages before event is recorded.
102
-	 *
103
-	 * 	@param	string	$action		Id of action in llx_c_action_trigger
104
-	 * 	@param	int		$socid		Id of third party
105
-	 *  @param	Object	$object		Object the notification is about
106
-	 *	@return	string				Message
107
-	 */
108
-	function confirmMessage($action,$socid,$object)
109
-	{
110
-		global $langs;
111
-		$langs->load("mails");
112
-
113
-		$listofnotiftodo=$this->getNotificationsArray($action,$socid,$object,0);
114
-
115
-		$nb=-1;
116
-		if (is_array($listofnotiftodo)) $nb=count($listofnotiftodo);
117
-		if ($nb < 0)  $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("ErrorFailedToGetListOfNotificationsToSend");
118
-		if ($nb == 0) $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("NoNotificationsWillBeSent");
119
-   		if ($nb == 1) $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("ANotificationsWillBeSent");
120
-   		if ($nb >= 2) $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("SomeNotificationsWillBeSent",$nb);
121
-
122
-   		if (is_array($listofnotiftodo))
123
-   		{
124
-			$i=0;
125
-			foreach ($listofnotiftodo as $key => $val)
126
-			{
127
-				if ($i) $texte.=', ';
128
-				else $texte.=' (';
129
-				if ($val['isemailvalid']) $texte.=$val['email'];
130
-				else $texte.=$val['emaildesc'];
131
-				$i++;
132
-			}
133
-			if ($i) $texte.=')';
134
-   		}
135
-
136
-		return $texte;
137
-	}
138
-
139
-	/**
140
-	 * Return number of notifications activated for action code (and third party)
141
-	 *
142
-	 * @param	string	$notifcode		Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage)
143
-	 * @param	int		$socid			Id of third party or 0 for all thirdparties or -1 for no thirdparties
144
-	 * @param	Object	$object			Object the notification is about (need it to check threshold value of some notifications)
145
-	 * @param	int		$userid         Id of user or 0 for all users or -1 for no users
146
-	 * @param   array   $scope          Scope where to search
147
-	 * @return	array|int				<0 if KO, array of notifications to send if OK
148
-	 */
149
-	function getNotificationsArray($notifcode, $socid=0, $object=null, $userid=0, $scope=array('thirdparty', 'user', 'global'))
150
-	{
151
-		global $conf, $user;
152
-
153
-		$error=0;
154
-		$resarray=array();
155
-
156
-		$valueforthreshold = 0;
157
-		if (is_object($object)) $valueforthreshold = $object->total_ht;
158
-
159
-		if (! $error)
160
-		{
161
-			if ($socid >= 0 && in_array('thirdparty', $scope))
162
-			{
163
-				$sql = "SELECT a.code, c.email, c.rowid";
164
-				$sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,";
165
-				$sql.= " ".MAIN_DB_PREFIX."socpeople as c,";
166
-				$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
167
-				$sql.= " ".MAIN_DB_PREFIX."societe as s";
168
-				$sql.= " WHERE n.fk_contact = c.rowid";
169
-				$sql.= " AND a.rowid = n.fk_action";
170
-				$sql.= " AND n.fk_soc = s.rowid";
171
-				if ($notifcode)
172
-				{
173
-					if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
174
-					else $sql.= " AND a.code = '".$notifcode."'";			// New usage
175
-				}
176
-				$sql.= " AND s.entity IN (".getEntity('societe').")";
177
-				if ($socid > 0) $sql.= " AND s.rowid = ".$socid;
178
-
179
-				dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG);
180
-
181
-				$resql = $this->db->query($sql);
182
-				if ($resql)
183
-				{
184
-					$num = $this->db->num_rows($resql);
185
-					$i=0;
186
-					while ($i < $num)
187
-					{
188
-						$obj = $this->db->fetch_object($resql);
189
-						if ($obj)
190
-						{
191
-							$newval2=trim($obj->email);
192
-							$isvalid=isValidEmail($newval2);
193
-							if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'tocontact', 'code'=>trim($obj->code), 'emaildesc'=>'Contact id '.$obj->rowid, 'email'=>$newval2, 'contactid'=>$obj->rowid, 'isemailvalid'=>$isvalid);
194
-						}
195
-						$i++;
196
-					}
197
-				}
198
-				else
199
-				{
200
-					$error++;
201
-					$this->error=$this->db->lasterror();
202
-				}
203
-			}
204
-		}
205
-
206
-		if (! $error)
207
-		{
208
-			if ($userid >= 0 && in_array('user', $scope))
209
-			{
210
-				$sql = "SELECT a.code, c.email, c.rowid";
211
-				$sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,";
212
-				$sql.= " ".MAIN_DB_PREFIX."user as c,";
213
-				$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a";
214
-				$sql.= " WHERE n.fk_user = c.rowid";
215
-				$sql.= " AND a.rowid = n.fk_action";
216
-				if ($notifcode)
217
-				{
218
-					if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
219
-					else $sql.= " AND a.code = '".$notifcode."'";			// New usage
220
-				}
221
-				$sql.= " AND c.entity IN (".getEntity('user').")";
222
-				if ($userid > 0) $sql.= " AND c.rowid = ".$userid;
223
-
224
-				dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG);
225
-
226
-				$resql = $this->db->query($sql);
227
-				if ($resql)
228
-				{
229
-					$num = $this->db->num_rows($resql);
230
-					$i=0;
231
-					while ($i < $num)
232
-					{
233
-						$obj = $this->db->fetch_object($resql);
234
-						if ($obj)
235
-						{
236
-							$newval2=trim($obj->email);
237
-							$isvalid=isValidEmail($newval2);
238
-							if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'touser', 'code'=>trim($obj->code), 'emaildesc'=>'User id '.$obj->rowid, 'email'=>$newval2, 'userid'=>$obj->rowid, 'isemailvalid'=>$isvalid);
239
-						}
240
-						$i++;
241
-					}
242
-				}
243
-				else
244
-				{
245
-					$error++;
246
-					$this->error=$this->db->lasterror();
247
-				}
248
-			}
249
-		}
250
-
251
-		if (! $error)
252
-		{
253
-			if (in_array('global', $scope))
254
-			{
255
-				// List of notifications enabled for fixed email
256
-				foreach($conf->global as $key => $val)
257
-				{
258
-					if ($notifcode)
259
-					{
260
-						if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue;
261
-					}
262
-					else
263
-					{
264
-						if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue;
265
-					}
266
-
267
-					$threshold = (float) $reg[1];
268
-					if ($valueforthreshold < $threshold) continue;
269
-
270
-					$tmpemail=explode(',',$val);
271
-					foreach($tmpemail as $key2 => $val2)
272
-					{
273
-						$newval2=trim($val2);
274
-						if ($newval2 == '__SUPERVISOREMAIL__')
275
-						{
276
-							if ($user->fk_user > 0)
277
-							{
278
-								$tmpuser=new User($this->db);
279
-								$tmpuser->fetch($user->fk_user);
280
-								if ($tmpuser->email) $newval2=trim($tmpuser->email);
281
-								else $newval2='';
282
-							}
283
-							else $newval2='';
284
-						}
285
-						if ($newval2)
286
-						{
287
-							$isvalid=isValidEmail($newval2, 0);
288
-							if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid);
289
-						}
290
-					}
291
-				}
292
-			}
293
-		}
294
-
295
-		if ($error) return -1;
296
-
297
-		//var_dump($resarray);
298
-		return $resarray;
299
-	}
300
-
301
-	/**
302
-	 *  Check if notification are active for couple action/company.
303
-	 * 	If yes, send mail and save trace into llx_notify.
304
-	 *
305
-	 * 	@param	string	$notifcode			Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage)
306
-	 * 	@param	Object	$object				Object the notification deals on
307
-	 *	@param 	array	$filename_list		List of files to attach (full path of filename on file system)
308
-	 *	@param 	array	$mimetype_list		List of MIME type of attached files
309
-	 *	@param 	array	$mimefilename_list	List of attached file name in message
310
-	 *	@return	int							<0 if KO, or number of changes if OK
311
-	 */
312
-	function send($notifcode, $object, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array())
313
-	{
314
-		global $user,$conf,$langs,$mysoc;
315
-		global $hookmanager;
316
-		global $dolibarr_main_url_root;
317
-
318
-		if (! in_array($notifcode, $this->arrayofnotifsupported)) return 0;
319
-
320
-		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
321
-		if (! is_object($hookmanager))
322
-		{
323
-			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
324
-			$hookmanager=new HookManager($this->db);
325
-		}
326
-		$hookmanager->initHooks(array('notification'));
327
-
328
-		dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id);
329
-
330
-		$langs->load("other");
331
-
332
-		// Define $urlwithroot
333
-		$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
334
-		$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;			// This is to use external domain name found into config file
335
-		//$urlwithroot=DOL_MAIN_URL_ROOT;						// This is to use same domain name than current
336
-
337
-		// Define some vars
338
-		$application = 'Dolibarr';
339
-		if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $application = $conf->global->MAIN_APPLICATION_TITLE;
340
-		$replyto = $conf->notification->email_from;
341
-		$object_type = '';
342
-		$link = '';
343
-		$num = 0;
344
-
345
-		$oldref=(empty($object->oldref)?$object->ref:$object->oldref);
346
-		$newref=(empty($object->newref)?$object->ref:$object->newref);
347
-
348
-		$sql = '';
349
-
350
-		// Check notification per third party
351
-		if ($object->socid > 0)
352
-		{
353
-			$sql.= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
354
-			$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
355
-			$sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
356
-			$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
357
-			$sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
358
-			$sql.= " ".MAIN_DB_PREFIX."societe as s";
359
-			$sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
360
-			$sql.= " AND n.fk_soc = s.rowid";
361
-			if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
362
-			else $sql.= " AND a.code = '".$notifcode."'";	// New usage
363
-			$sql .= " AND s.rowid = ".$object->socid;
364
-
365
-			$sql.= "\nUNION\n";
366
-		}
367
-
368
-		// Check notification per user
369
-		$sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
370
-		$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
371
-		$sql.= " FROM ".MAIN_DB_PREFIX."user as c,";
372
-		$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
373
-		$sql.= " ".MAIN_DB_PREFIX."notify_def as n";
374
-		$sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
375
-		if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
376
-		else $sql.= " AND a.code = '".$this->db->escape($notifcode)."'";	// New usage
377
-
378
-		$result = $this->db->query($sql);
379
-		if ($result)
380
-		{
381
-			$num = $this->db->num_rows($result);
382
-			$projtitle='';
383
-			if (! empty($object->fk_project))
384
-			{
385
-				require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
386
-				$proj = new Project($this->db);
387
-				$proj->fetch($object->fk_project);
388
-				$projtitle='('.$proj->title.')';
389
-			}
390
-
391
-			if ($num > 0)
392
-			{
393
-				$i = 0;
394
-				while ($i < $num && ! $error)	// For each notification couple defined (third party/actioncode)
395
-				{
396
-					$obj = $this->db->fetch_object($result);
397
-
398
-					$sendto = dolGetFirstLastname($obj->firstname,$obj->lastname) . " <".$obj->email.">";
399
-					$notifcodedefid = $obj->adid;
400
-
401
-					if (dol_strlen($obj->email))
402
-					{
403
-						// Set output language
404
-						$outputlangs = $langs;
405
-						if ($obj->default_lang && $obj->default_lang != $langs->defaultlang)
406
-						{
407
-							$outputlangs = new Translate('', $conf);
408
-							$outputlangs->setDefaultLang($obj->default_lang);
409
-							$outputlangs->loadLangs(array("main","other"));
410
-						}
411
-
412
-						$subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
413
-
414
-						switch ($notifcode) {
415
-							case 'BILL_VALIDATE':
416
-								$link='/compta/facture/card.php?facid='.$object->id;
417
-								$dir_output = $conf->facture->dir_output;
418
-								$object_type = 'facture';
419
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref);
420
-								break;
421
-							case 'BILL_PAYED':
422
-								$link='/compta/facture/card.php?facid='.$object->id;
423
-								$dir_output = $conf->facture->dir_output;
424
-								$object_type = 'facture';
425
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref);
426
-								break;
427
-							case 'ORDER_VALIDATE':
428
-								$link='/commande/card.php?id='.$object->id;
429
-								$dir_output = $conf->commande->dir_output;
430
-								$object_type = 'order';
431
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated",$newref);
432
-								break;
433
-							case 'PROPAL_VALIDATE':
434
-								$link='/comm/propal/card.php?id='.$object->id;
435
-								$dir_output = $conf->propal->multidir_output[$object->entity];
436
-								$object_type = 'propal';
437
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated",$newref);
438
-								break;
439
-							case 'PROPAL_CLOSE_SIGNED':
440
-								$link='/comm/propal/card.php?id='.$object->id;
441
-								$dir_output = $conf->propal->multidir_output[$object->entity];
442
-								$object_type = 'propal';
443
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref);
444
-								break;
445
-							case 'FICHINTER_ADD_CONTACT':
446
-								$link='/fichinter/card.php?id='.$object->id;
447
-								$dir_output = $conf->ficheinter->dir_output;
448
-								$object_type = 'ficheinter';
449
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$newref);
450
-								break;
451
-							case 'FICHINTER_VALIDATE':
452
-								$link='/fichinter/card.php?id='.$object->id;
453
-								$dir_output = $conf->ficheinter->dir_output;
454
-								$object_type = 'ficheinter';
455
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated",$newref);
456
-								break;
457
-							case 'ORDER_SUPPLIER_VALIDATE':
458
-								$link='/fourn/commande/card.php?id='.$object->id;
459
-								$dir_output = $conf->fournisseur->commande->dir_output;
460
-								$object_type = 'order_supplier';
461
-								$mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
462
-								$mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$newref,$user->getFullName($langs));
463
-								$mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
464
-								break;
465
-							case 'ORDER_SUPPLIER_APPROVE':
466
-								$link='/fourn/commande/card.php?id='.$object->id;
467
-								$dir_output = $conf->fournisseur->commande->dir_output;
468
-								$object_type = 'order_supplier';
469
-								$mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
470
-								$mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$newref,$user->getFullName($langs));
471
-								$mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
472
-								break;
473
-							case 'ORDER_SUPPLIER_REFUSE':
474
-								$link='/fourn/commande/card.php?id='.$object->id;
475
-								$dir_output = $conf->fournisseur->commande->dir_output;
476
-								$object_type = 'order_supplier';
477
-								$mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
478
-								$mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$newref,$user->getFullName($langs));
479
-								$mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
480
-								break;
481
-							case 'SHIPPING_VALIDATE':
482
-								$dir_output = $conf->expedition->dir_output.'/sending/';
483
-								$object_type = 'order_supplier';
484
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
485
-								break;
486
-							case 'EXPENSE_REPORT_VALIDATE':
487
-								$dir_output = $conf->expensereport->dir_output;
488
-								$object_type = 'expensereport';
489
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
490
-								break;
491
-							case 'EXPENSE_REPORT_APPROVE':
492
-								$dir_output = $conf->expensereport->dir_output;
493
-								$object_type = 'expensereport';
494
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
495
-								break;
496
-							case 'HOLIDAY_VALIDATE':
497
-								$dir_output = $conf->holiday->dir_output;
498
-								$object_type = 'holiday';
499
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
500
-								break;
501
-							case 'HOLIDAY_APPROVE':
502
-								$dir_output = $conf->holiday->dir_output;
503
-								$object_type = 'holiday';
504
-								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
505
-								break;
506
-						}
507
-						$ref = dol_sanitizeFileName($newref);
508
-						$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
509
-						if (! dol_is_file($pdf_path))
510
-						{
511
-							// We can't add PDF as it is not generated yet.
512
-							$filepdf = '';
513
-						}
514
-						else
515
-						{
516
-							$filepdf = $pdf_path;
517
-						}
518
-
519
-						$message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n";
520
-						$message.= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n";
521
-						$message.= "\n";
522
-						$message.= $mesg;
523
-						if ($link) $message.= "\n" . $urlwithroot . $link;
524
-
525
-						$parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list);
526
-						$reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
527
-						if (empty($reshook))
528
-						{
529
-							if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject'];
530
-							if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message'];
531
-						}
532
-
533
-						$mailfile = new CMailFile(
534
-							$subject,
535
-							$sendto,
536
-							$replyto,
537
-							$message,
538
-							$filename_list,
539
-							$mimetype_list,
540
-							$mimefilename_list,
541
-							'',
542
-							'',
543
-							0,
544
-							-1
545
-						);
546
-
547
-						if ($mailfile->sendfile())
548
-						{
549
-							if ($obj->type_target == 'touserid') {
550
-	 							$sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_user, type, objet_type, type_target, objet_id, email)";
551
-								$sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')";
552
-							}
553
-							else {
554
-								$sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, objet_type, type_target, objet_id, email)";
555
-								$sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')";
556
-							}
557
-							if (! $this->db->query($sql))
558
-							{
559
-								dol_print_error($this->db);
560
-							}
561
-						}
562
-						else
563
-						{
564
-							$error++;
565
-							$this->errors[]=$mailfile->error;
566
-						}
567
-					}
568
-					else
569
-				  {
570
-						dol_syslog("No notification sent for ".$sendto." because email is empty");
571
-					}
572
-					$i++;
573
-				}
574
-			}
575
-			else
576
-			{
577
-				dol_syslog("No notification to thirdparty sent, nothing into notification setup for the thirdparty socid = ".$object->socid);
578
-			}
579
-		}
580
-		else
581
-		{
582
-	   		$error++;
583
-			$this->errors[]=$this->db->lasterror();
584
-			dol_syslog("Failed to get list of notification to send ".$this->db->lasterror(), LOG_ERR);
585
-	   		return -1;
586
-		}
587
-
588
-		// Check notification using fixed email
589
-		if (! $error)
590
-		{
591
-			foreach($conf->global as $key => $val)
592
-			{
593
-				if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue;
594
-
595
-				$threshold = (float) $reg[1];
596
-				if (!empty($object->total_ht) && $object->total_ht <= $threshold)
597
-				{
598
-					dol_syslog("A notification is requested for notifcode = ".$notifcode." but amount = ".$object->total_ht." so lower than threshold = ".$threshold.". We discard this notification");
599
-					continue;
600
-				}
601
-
602
-				$param='NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_'.$reg[1];
603
-
604
-				$sendto = $conf->global->$param;
605
-				$notifcodedefid = dol_getIdFromCode($this->db, $notifcode, 'c_action_trigger', 'code', 'rowid');
606
-				if ($notifcodedefid <= 0) dol_print_error($this->db, 'Failed to get id from code');
607
-
608
-				$object_type = '';
609
-				$link = '';
610
-				$num++;
611
-
612
-				$subject = '['.$mysoc->name.'] '.$langs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
613
-
614
-				switch ($notifcode) {
615
-					case 'BILL_VALIDATE':
616
-						$link = '<a href="' . $urlwithroot . '/compta/facture/card.php?facid=' . $object->id . '">' . $newref . '</a>';
617
-						$dir_output = $conf->facture->dir_output;
618
-						$object_type = 'facture';
619
-						$mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated",$link);
620
-						break;
621
-					case 'BILL_PAYED':
622
-						$link ='<a href="' . $urlwithroot . '/compta/facture/card.php?facid='.$object->id . '">' . $newref . '</a>';
623
-						$dir_output = $conf->facture->dir_output;
624
-						$object_type = 'facture';
625
-						$mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed",$link);
626
-						break;
627
-					case 'ORDER_VALIDATE':
628
-						$link = '<a href="' . $urlwithroot . '/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
629
-						$dir_output = $conf->commande->dir_output;
630
-						$object_type = 'order';
631
-						$mesg = $langs->transnoentitiesnoconv("EMailTextOrderValidated",$link);
632
-						break;
633
-					case 'PROPAL_VALIDATE':
634
-						$link = '<a href="' . $urlwithroot . '/comm/propal/card.php?id='.$object->id . '">' . $newref . '</a>';
635
-						$dir_output = $conf->propal->multidir_output[$object->entity];
636
-						$object_type = 'propal';
637
-						$mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$link);
638
-						break;
639
-					case 'PROPAL_CLOSE_SIGNED':
640
-						$link = '<a href="' . $urlwithroot . '/comm/propal/card.php?id='.$object->id . '">' . $newref . '</a>';
641
-						$dir_output = $conf->propal->multidir_output[$object->entity];
642
-						$object_type = 'propal';
643
-						$mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$link);
644
-						break;
645
-					case 'FICHINTER_ADD_CONTACT':
646
-						$link = '<a href="' . $urlwithroot . '/fichinter/card.php?id='.$object->id . '">' . $newref . '</a>';
647
-						$dir_output = $conf->facture->dir_output;
648
-						$object_type = 'ficheinter';
649
-						$mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$link);
650
-						break;
651
-					case 'FICHINTER_VALIDATE':
652
-						$link = '<a href="' . $urlwithroot . '/fichinter/card.php?id='.$object->id . '">' . $newref . '</a>';
653
-						$dir_output = $conf->facture->dir_output;
654
-						$object_type = 'ficheinter';
655
-						$mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated",$link);
656
-						break;
657
-					case 'ORDER_SUPPLIER_VALIDATE':
658
-						$link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
659
-						$dir_output = $conf->fournisseur->commande->dir_output;
660
-						$object_type = 'order_supplier';
661
-						$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
662
-						$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$link,$user->getFullName($langs));
663
-						$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
664
-						break;
665
-					case 'ORDER_SUPPLIER_APPROVE':
666
-						$link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
667
-						$dir_output = $conf->fournisseur->commande->dir_output;
668
-						$object_type = 'order_supplier';
669
-						$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
670
-						$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$link,$user->getFullName($langs));
671
-						$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
672
-						break;
673
-					case 'ORDER_SUPPLIER_APPROVE2':
674
-						$link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
675
-						$dir_output = $conf->fournisseur->commande->dir_output;
676
-						$object_type = 'order_supplier';
677
-						$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
678
-						$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$link,$user->getFullName($langs));
679
-						$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
680
-						break;
681
-					case 'ORDER_SUPPLIER_REFUSE':
682
-						$link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
683
-						$dir_output = $conf->fournisseur->dir_output.'/commande/';
684
-						$object_type = 'order_supplier';
685
-						$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
686
-						$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$link,$user->getFullName($langs));
687
-						$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
688
-						break;
689
-					case 'SHIPPING_VALIDATE':
690
-						$dir_output = $conf->expedition->dir_output.'/sending/';
691
-						$object_type = 'order_supplier';
692
-						$mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
693
-						break;
694
-					case 'EXPENSE_REPORT_VALIDATE':
695
-						$dir_output = $conf->expensereport->dir_output;
696
-						$object_type = 'expensereport';
697
-						$mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
698
-						break;
699
-					case 'EXPENSE_REPORT_APPROVE':
700
-						$dir_output = $conf->expensereport->dir_output;
701
-						$object_type = 'expensereport';
702
-						$mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
703
-						break;
704
-					case 'HOLIDAY_VALIDATE':
705
-						$dir_output = $conf->holiday->dir_output;
706
-						$object_type = 'holiday';
707
-						$mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
708
-						break;
709
-					case 'HOLIDAY_APPROVE':
710
-						$dir_output = $conf->holiday->dir_output;
711
-						$object_type = 'holiday';
712
-						$mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
713
-						break;
714
-				}
715
-				$ref = dol_sanitizeFileName($newref);
716
-				$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
717
-				if (! dol_is_file($pdf_path))
718
-				{
719
-					// We can't add PDF as it is not generated yet.
720
-					$filepdf = '';
721
-				}
722
-				else
723
-				{
724
-					$filepdf = $pdf_path;
725
-				}
726
-
727
-				$message = $langs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n";
728
-				$message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n";
729
-				$message.= "\n";
730
-				$message.= $mesg;
731
-				//if ($link) $message.= "\n" . $urlwithroot . $link;	// link already added around the ref into the text
732
-
733
-				$message = nl2br($message);
734
-
735
-				// Replace keyword __SUPERVISOREMAIL__
736
-				if (preg_match('/__SUPERVISOREMAIL__/', $sendto))
737
-				{
738
-					$newval='';
739
-					if ($user->fk_user > 0)
740
-					{
741
-						$supervisoruser=new User($this->db);
742
-						$supervisoruser->fetch($user->fk_user);
743
-						if ($supervisoruser->email) $newval=trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>');
744
-					}
745
-					dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
746
-					$sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
747
-					$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
748
-					$sendto = preg_replace('/^[\s,]+/', '', $sendto);	// Clean start of string
749
-					$sendto = preg_replace('/[\s,]+$/', '', $sendto);	// Clean end of string
750
-				}
751
-
752
-				if ($sendto)
753
-				{
754
-					$parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list);
755
-					$reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
756
-					if (empty($reshook))
757
-					{
758
-						if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject'];
759
-						if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message'];
760
-					}
761
-					$mailfile = new CMailFile(
762
-						$subject,
763
-						$sendto,
764
-						$replyto,
765
-						$message,
766
-						$filename_list,
767
-						$mimetype_list,
768
-						$mimefilename_list,
769
-						'',
770
-						'',
771
-						0,
772
-						1
773
-					);
774
-
775
-					if ($mailfile->sendfile())
776
-					{
777
-						$sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, type_target, objet_type, objet_id, email)";
778
-						$sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", null, 'email', 'tofixedemail', '".$object_type."', ".$object->id.", '".$this->db->escape($conf->global->$param)."')";
779
-						if (! $this->db->query($sql))
780
-						{
781
-							dol_print_error($this->db);
782
-						}
783
-					}
784
-					else
785
-					{
786
-						$error++;
787
-						$this->errors[]=$mailfile->error;
788
-					}
789
-				}
790
-			}
791
-		}
792
-
793
-		if (! $error) return $num;
794
-		else return -1 * $error;
795
-	}
65
+    // Les codes actions sont definis dans la table llx_notify_def
66
+
67
+    // codes actions supported are
68
+    // @TODO defined also into interface_50_modNotificiation_Notificiation.class.php
69
+    public $arrayofnotifsupported = array(
70
+        'BILL_VALIDATE',
71
+        'BILL_PAYED',
72
+        'ORDER_VALIDATE',
73
+        'PROPAL_VALIDATE',
74
+        'PROPAL_CLOSE_SIGNED',
75
+        'FICHINTER_VALIDATE',
76
+        'FICHINTER_ADD_CONTACT',
77
+        'ORDER_SUPPLIER_VALIDATE',
78
+        'ORDER_SUPPLIER_APPROVE',
79
+        'ORDER_SUPPLIER_REFUSE',
80
+        'SHIPPING_VALIDATE',
81
+        'EXPENSE_REPORT_VALIDATE',
82
+        'EXPENSE_REPORT_APPROVE',
83
+        'HOLIDAY_VALIDATE',
84
+        'HOLIDAY_APPROVE'
85
+    );
86
+
87
+
88
+    /**
89
+     *	Constructor
90
+     *
91
+     *	@param 		DoliDB		$db		Database handler
92
+     */
93
+    function __construct($db)
94
+    {
95
+        $this->db = $db;
96
+    }
97
+
98
+
99
+    /**
100
+     *  Return message that say how many notification (and to which email) will occurs on requested event.
101
+     *	This is to show confirmation messages before event is recorded.
102
+     *
103
+     * 	@param	string	$action		Id of action in llx_c_action_trigger
104
+     * 	@param	int		$socid		Id of third party
105
+     *  @param	Object	$object		Object the notification is about
106
+     *	@return	string				Message
107
+     */
108
+    function confirmMessage($action,$socid,$object)
109
+    {
110
+        global $langs;
111
+        $langs->load("mails");
112
+
113
+        $listofnotiftodo=$this->getNotificationsArray($action,$socid,$object,0);
114
+
115
+        $nb=-1;
116
+        if (is_array($listofnotiftodo)) $nb=count($listofnotiftodo);
117
+        if ($nb < 0)  $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("ErrorFailedToGetListOfNotificationsToSend");
118
+        if ($nb == 0) $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("NoNotificationsWillBeSent");
119
+            if ($nb == 1) $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("ANotificationsWillBeSent");
120
+            if ($nb >= 2) $texte=img_object($langs->trans("Notifications"),'email').' '.$langs->trans("SomeNotificationsWillBeSent",$nb);
121
+
122
+            if (is_array($listofnotiftodo))
123
+            {
124
+            $i=0;
125
+            foreach ($listofnotiftodo as $key => $val)
126
+            {
127
+                if ($i) $texte.=', ';
128
+                else $texte.=' (';
129
+                if ($val['isemailvalid']) $texte.=$val['email'];
130
+                else $texte.=$val['emaildesc'];
131
+                $i++;
132
+            }
133
+            if ($i) $texte.=')';
134
+            }
135
+
136
+        return $texte;
137
+    }
138
+
139
+    /**
140
+     * Return number of notifications activated for action code (and third party)
141
+     *
142
+     * @param	string	$notifcode		Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage)
143
+     * @param	int		$socid			Id of third party or 0 for all thirdparties or -1 for no thirdparties
144
+     * @param	Object	$object			Object the notification is about (need it to check threshold value of some notifications)
145
+     * @param	int		$userid         Id of user or 0 for all users or -1 for no users
146
+     * @param   array   $scope          Scope where to search
147
+     * @return	array|int				<0 if KO, array of notifications to send if OK
148
+     */
149
+    function getNotificationsArray($notifcode, $socid=0, $object=null, $userid=0, $scope=array('thirdparty', 'user', 'global'))
150
+    {
151
+        global $conf, $user;
152
+
153
+        $error=0;
154
+        $resarray=array();
155
+
156
+        $valueforthreshold = 0;
157
+        if (is_object($object)) $valueforthreshold = $object->total_ht;
158
+
159
+        if (! $error)
160
+        {
161
+            if ($socid >= 0 && in_array('thirdparty', $scope))
162
+            {
163
+                $sql = "SELECT a.code, c.email, c.rowid";
164
+                $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,";
165
+                $sql.= " ".MAIN_DB_PREFIX."socpeople as c,";
166
+                $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
167
+                $sql.= " ".MAIN_DB_PREFIX."societe as s";
168
+                $sql.= " WHERE n.fk_contact = c.rowid";
169
+                $sql.= " AND a.rowid = n.fk_action";
170
+                $sql.= " AND n.fk_soc = s.rowid";
171
+                if ($notifcode)
172
+                {
173
+                    if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
174
+                    else $sql.= " AND a.code = '".$notifcode."'";			// New usage
175
+                }
176
+                $sql.= " AND s.entity IN (".getEntity('societe').")";
177
+                if ($socid > 0) $sql.= " AND s.rowid = ".$socid;
178
+
179
+                dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG);
180
+
181
+                $resql = $this->db->query($sql);
182
+                if ($resql)
183
+                {
184
+                    $num = $this->db->num_rows($resql);
185
+                    $i=0;
186
+                    while ($i < $num)
187
+                    {
188
+                        $obj = $this->db->fetch_object($resql);
189
+                        if ($obj)
190
+                        {
191
+                            $newval2=trim($obj->email);
192
+                            $isvalid=isValidEmail($newval2);
193
+                            if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'tocontact', 'code'=>trim($obj->code), 'emaildesc'=>'Contact id '.$obj->rowid, 'email'=>$newval2, 'contactid'=>$obj->rowid, 'isemailvalid'=>$isvalid);
194
+                        }
195
+                        $i++;
196
+                    }
197
+                }
198
+                else
199
+                {
200
+                    $error++;
201
+                    $this->error=$this->db->lasterror();
202
+                }
203
+            }
204
+        }
205
+
206
+        if (! $error)
207
+        {
208
+            if ($userid >= 0 && in_array('user', $scope))
209
+            {
210
+                $sql = "SELECT a.code, c.email, c.rowid";
211
+                $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n,";
212
+                $sql.= " ".MAIN_DB_PREFIX."user as c,";
213
+                $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a";
214
+                $sql.= " WHERE n.fk_user = c.rowid";
215
+                $sql.= " AND a.rowid = n.fk_action";
216
+                if ($notifcode)
217
+                {
218
+                    if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
219
+                    else $sql.= " AND a.code = '".$notifcode."'";			// New usage
220
+                }
221
+                $sql.= " AND c.entity IN (".getEntity('user').")";
222
+                if ($userid > 0) $sql.= " AND c.rowid = ".$userid;
223
+
224
+                dol_syslog(__METHOD__." ".$notifcode.", ".$socid."", LOG_DEBUG);
225
+
226
+                $resql = $this->db->query($sql);
227
+                if ($resql)
228
+                {
229
+                    $num = $this->db->num_rows($resql);
230
+                    $i=0;
231
+                    while ($i < $num)
232
+                    {
233
+                        $obj = $this->db->fetch_object($resql);
234
+                        if ($obj)
235
+                        {
236
+                            $newval2=trim($obj->email);
237
+                            $isvalid=isValidEmail($newval2);
238
+                            if (empty($resarray[$newval2])) $resarray[$newval2] = array('type'=> 'touser', 'code'=>trim($obj->code), 'emaildesc'=>'User id '.$obj->rowid, 'email'=>$newval2, 'userid'=>$obj->rowid, 'isemailvalid'=>$isvalid);
239
+                        }
240
+                        $i++;
241
+                    }
242
+                }
243
+                else
244
+                {
245
+                    $error++;
246
+                    $this->error=$this->db->lasterror();
247
+                }
248
+            }
249
+        }
250
+
251
+        if (! $error)
252
+        {
253
+            if (in_array('global', $scope))
254
+            {
255
+                // List of notifications enabled for fixed email
256
+                foreach($conf->global as $key => $val)
257
+                {
258
+                    if ($notifcode)
259
+                    {
260
+                        if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue;
261
+                    }
262
+                    else
263
+                    {
264
+                        if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue;
265
+                    }
266
+
267
+                    $threshold = (float) $reg[1];
268
+                    if ($valueforthreshold < $threshold) continue;
269
+
270
+                    $tmpemail=explode(',',$val);
271
+                    foreach($tmpemail as $key2 => $val2)
272
+                    {
273
+                        $newval2=trim($val2);
274
+                        if ($newval2 == '__SUPERVISOREMAIL__')
275
+                        {
276
+                            if ($user->fk_user > 0)
277
+                            {
278
+                                $tmpuser=new User($this->db);
279
+                                $tmpuser->fetch($user->fk_user);
280
+                                if ($tmpuser->email) $newval2=trim($tmpuser->email);
281
+                                else $newval2='';
282
+                            }
283
+                            else $newval2='';
284
+                        }
285
+                        if ($newval2)
286
+                        {
287
+                            $isvalid=isValidEmail($newval2, 0);
288
+                            if (empty($resarray[$newval2])) $resarray[$newval2]=array('type'=> 'tofixedemail', 'code'=>trim($key), 'emaildesc'=>trim($val2), 'email'=>$newval2, 'isemailvalid'=>$isvalid);
289
+                        }
290
+                    }
291
+                }
292
+            }
293
+        }
294
+
295
+        if ($error) return -1;
296
+
297
+        //var_dump($resarray);
298
+        return $resarray;
299
+    }
300
+
301
+    /**
302
+     *  Check if notification are active for couple action/company.
303
+     * 	If yes, send mail and save trace into llx_notify.
304
+     *
305
+     * 	@param	string	$notifcode			Code of action in llx_c_action_trigger (new usage) or Id of action in llx_c_action_trigger (old usage)
306
+     * 	@param	Object	$object				Object the notification deals on
307
+     *	@param 	array	$filename_list		List of files to attach (full path of filename on file system)
308
+     *	@param 	array	$mimetype_list		List of MIME type of attached files
309
+     *	@param 	array	$mimefilename_list	List of attached file name in message
310
+     *	@return	int							<0 if KO, or number of changes if OK
311
+     */
312
+    function send($notifcode, $object, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array())
313
+    {
314
+        global $user,$conf,$langs,$mysoc;
315
+        global $hookmanager;
316
+        global $dolibarr_main_url_root;
317
+
318
+        if (! in_array($notifcode, $this->arrayofnotifsupported)) return 0;
319
+
320
+        include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
321
+        if (! is_object($hookmanager))
322
+        {
323
+            include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
324
+            $hookmanager=new HookManager($this->db);
325
+        }
326
+        $hookmanager->initHooks(array('notification'));
327
+
328
+        dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id);
329
+
330
+        $langs->load("other");
331
+
332
+        // Define $urlwithroot
333
+        $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
334
+        $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;			// This is to use external domain name found into config file
335
+        //$urlwithroot=DOL_MAIN_URL_ROOT;						// This is to use same domain name than current
336
+
337
+        // Define some vars
338
+        $application = 'Dolibarr';
339
+        if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $application = $conf->global->MAIN_APPLICATION_TITLE;
340
+        $replyto = $conf->notification->email_from;
341
+        $object_type = '';
342
+        $link = '';
343
+        $num = 0;
344
+
345
+        $oldref=(empty($object->oldref)?$object->ref:$object->oldref);
346
+        $newref=(empty($object->newref)?$object->ref:$object->newref);
347
+
348
+        $sql = '';
349
+
350
+        // Check notification per third party
351
+        if ($object->socid > 0)
352
+        {
353
+            $sql.= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
354
+            $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
355
+            $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
356
+            $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
357
+            $sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
358
+            $sql.= " ".MAIN_DB_PREFIX."societe as s";
359
+            $sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
360
+            $sql.= " AND n.fk_soc = s.rowid";
361
+            if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
362
+            else $sql.= " AND a.code = '".$notifcode."'";	// New usage
363
+            $sql .= " AND s.rowid = ".$object->socid;
364
+
365
+            $sql.= "\nUNION\n";
366
+        }
367
+
368
+        // Check notification per user
369
+        $sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
370
+        $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
371
+        $sql.= " FROM ".MAIN_DB_PREFIX."user as c,";
372
+        $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
373
+        $sql.= " ".MAIN_DB_PREFIX."notify_def as n";
374
+        $sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
375
+        if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
376
+        else $sql.= " AND a.code = '".$this->db->escape($notifcode)."'";	// New usage
377
+
378
+        $result = $this->db->query($sql);
379
+        if ($result)
380
+        {
381
+            $num = $this->db->num_rows($result);
382
+            $projtitle='';
383
+            if (! empty($object->fk_project))
384
+            {
385
+                require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
386
+                $proj = new Project($this->db);
387
+                $proj->fetch($object->fk_project);
388
+                $projtitle='('.$proj->title.')';
389
+            }
390
+
391
+            if ($num > 0)
392
+            {
393
+                $i = 0;
394
+                while ($i < $num && ! $error)	// For each notification couple defined (third party/actioncode)
395
+                {
396
+                    $obj = $this->db->fetch_object($result);
397
+
398
+                    $sendto = dolGetFirstLastname($obj->firstname,$obj->lastname) . " <".$obj->email.">";
399
+                    $notifcodedefid = $obj->adid;
400
+
401
+                    if (dol_strlen($obj->email))
402
+                    {
403
+                        // Set output language
404
+                        $outputlangs = $langs;
405
+                        if ($obj->default_lang && $obj->default_lang != $langs->defaultlang)
406
+                        {
407
+                            $outputlangs = new Translate('', $conf);
408
+                            $outputlangs->setDefaultLang($obj->default_lang);
409
+                            $outputlangs->loadLangs(array("main","other"));
410
+                        }
411
+
412
+                        $subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
413
+
414
+                        switch ($notifcode) {
415
+                            case 'BILL_VALIDATE':
416
+                                $link='/compta/facture/card.php?facid='.$object->id;
417
+                                $dir_output = $conf->facture->dir_output;
418
+                                $object_type = 'facture';
419
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref);
420
+                                break;
421
+                            case 'BILL_PAYED':
422
+                                $link='/compta/facture/card.php?facid='.$object->id;
423
+                                $dir_output = $conf->facture->dir_output;
424
+                                $object_type = 'facture';
425
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref);
426
+                                break;
427
+                            case 'ORDER_VALIDATE':
428
+                                $link='/commande/card.php?id='.$object->id;
429
+                                $dir_output = $conf->commande->dir_output;
430
+                                $object_type = 'order';
431
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated",$newref);
432
+                                break;
433
+                            case 'PROPAL_VALIDATE':
434
+                                $link='/comm/propal/card.php?id='.$object->id;
435
+                                $dir_output = $conf->propal->multidir_output[$object->entity];
436
+                                $object_type = 'propal';
437
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated",$newref);
438
+                                break;
439
+                            case 'PROPAL_CLOSE_SIGNED':
440
+                                $link='/comm/propal/card.php?id='.$object->id;
441
+                                $dir_output = $conf->propal->multidir_output[$object->entity];
442
+                                $object_type = 'propal';
443
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref);
444
+                                break;
445
+                            case 'FICHINTER_ADD_CONTACT':
446
+                                $link='/fichinter/card.php?id='.$object->id;
447
+                                $dir_output = $conf->ficheinter->dir_output;
448
+                                $object_type = 'ficheinter';
449
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$newref);
450
+                                break;
451
+                            case 'FICHINTER_VALIDATE':
452
+                                $link='/fichinter/card.php?id='.$object->id;
453
+                                $dir_output = $conf->ficheinter->dir_output;
454
+                                $object_type = 'ficheinter';
455
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated",$newref);
456
+                                break;
457
+                            case 'ORDER_SUPPLIER_VALIDATE':
458
+                                $link='/fourn/commande/card.php?id='.$object->id;
459
+                                $dir_output = $conf->fournisseur->commande->dir_output;
460
+                                $object_type = 'order_supplier';
461
+                                $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
462
+                                $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$newref,$user->getFullName($langs));
463
+                                $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
464
+                                break;
465
+                            case 'ORDER_SUPPLIER_APPROVE':
466
+                                $link='/fourn/commande/card.php?id='.$object->id;
467
+                                $dir_output = $conf->fournisseur->commande->dir_output;
468
+                                $object_type = 'order_supplier';
469
+                                $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
470
+                                $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$newref,$user->getFullName($langs));
471
+                                $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
472
+                                break;
473
+                            case 'ORDER_SUPPLIER_REFUSE':
474
+                                $link='/fourn/commande/card.php?id='.$object->id;
475
+                                $dir_output = $conf->fournisseur->commande->dir_output;
476
+                                $object_type = 'order_supplier';
477
+                                $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
478
+                                $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$newref,$user->getFullName($langs));
479
+                                $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
480
+                                break;
481
+                            case 'SHIPPING_VALIDATE':
482
+                                $dir_output = $conf->expedition->dir_output.'/sending/';
483
+                                $object_type = 'order_supplier';
484
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
485
+                                break;
486
+                            case 'EXPENSE_REPORT_VALIDATE':
487
+                                $dir_output = $conf->expensereport->dir_output;
488
+                                $object_type = 'expensereport';
489
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
490
+                                break;
491
+                            case 'EXPENSE_REPORT_APPROVE':
492
+                                $dir_output = $conf->expensereport->dir_output;
493
+                                $object_type = 'expensereport';
494
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
495
+                                break;
496
+                            case 'HOLIDAY_VALIDATE':
497
+                                $dir_output = $conf->holiday->dir_output;
498
+                                $object_type = 'holiday';
499
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
500
+                                break;
501
+                            case 'HOLIDAY_APPROVE':
502
+                                $dir_output = $conf->holiday->dir_output;
503
+                                $object_type = 'holiday';
504
+                                $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
505
+                                break;
506
+                        }
507
+                        $ref = dol_sanitizeFileName($newref);
508
+                        $pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
509
+                        if (! dol_is_file($pdf_path))
510
+                        {
511
+                            // We can't add PDF as it is not generated yet.
512
+                            $filepdf = '';
513
+                        }
514
+                        else
515
+                        {
516
+                            $filepdf = $pdf_path;
517
+                        }
518
+
519
+                        $message = $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n";
520
+                        $message.= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n";
521
+                        $message.= "\n";
522
+                        $message.= $mesg;
523
+                        if ($link) $message.= "\n" . $urlwithroot . $link;
524
+
525
+                        $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list);
526
+                        $reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
527
+                        if (empty($reshook))
528
+                        {
529
+                            if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject'];
530
+                            if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message'];
531
+                        }
532
+
533
+                        $mailfile = new CMailFile(
534
+                            $subject,
535
+                            $sendto,
536
+                            $replyto,
537
+                            $message,
538
+                            $filename_list,
539
+                            $mimetype_list,
540
+                            $mimefilename_list,
541
+                            '',
542
+                            '',
543
+                            0,
544
+                            -1
545
+                        );
546
+
547
+                        if ($mailfile->sendfile())
548
+                        {
549
+                            if ($obj->type_target == 'touserid') {
550
+                                    $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_user, type, objet_type, type_target, objet_id, email)";
551
+                                $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')";
552
+                            }
553
+                            else {
554
+                                $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, objet_type, type_target, objet_id, email)";
555
+                                $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')";
556
+                            }
557
+                            if (! $this->db->query($sql))
558
+                            {
559
+                                dol_print_error($this->db);
560
+                            }
561
+                        }
562
+                        else
563
+                        {
564
+                            $error++;
565
+                            $this->errors[]=$mailfile->error;
566
+                        }
567
+                    }
568
+                    else
569
+                    {
570
+                        dol_syslog("No notification sent for ".$sendto." because email is empty");
571
+                    }
572
+                    $i++;
573
+                }
574
+            }
575
+            else
576
+            {
577
+                dol_syslog("No notification to thirdparty sent, nothing into notification setup for the thirdparty socid = ".$object->socid);
578
+            }
579
+        }
580
+        else
581
+        {
582
+                $error++;
583
+            $this->errors[]=$this->db->lasterror();
584
+            dol_syslog("Failed to get list of notification to send ".$this->db->lasterror(), LOG_ERR);
585
+                return -1;
586
+        }
587
+
588
+        // Check notification using fixed email
589
+        if (! $error)
590
+        {
591
+            foreach($conf->global as $key => $val)
592
+            {
593
+                if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue;
594
+
595
+                $threshold = (float) $reg[1];
596
+                if (!empty($object->total_ht) && $object->total_ht <= $threshold)
597
+                {
598
+                    dol_syslog("A notification is requested for notifcode = ".$notifcode." but amount = ".$object->total_ht." so lower than threshold = ".$threshold.". We discard this notification");
599
+                    continue;
600
+                }
601
+
602
+                $param='NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_'.$reg[1];
603
+
604
+                $sendto = $conf->global->$param;
605
+                $notifcodedefid = dol_getIdFromCode($this->db, $notifcode, 'c_action_trigger', 'code', 'rowid');
606
+                if ($notifcodedefid <= 0) dol_print_error($this->db, 'Failed to get id from code');
607
+
608
+                $object_type = '';
609
+                $link = '';
610
+                $num++;
611
+
612
+                $subject = '['.$mysoc->name.'] '.$langs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
613
+
614
+                switch ($notifcode) {
615
+                    case 'BILL_VALIDATE':
616
+                        $link = '<a href="' . $urlwithroot . '/compta/facture/card.php?facid=' . $object->id . '">' . $newref . '</a>';
617
+                        $dir_output = $conf->facture->dir_output;
618
+                        $object_type = 'facture';
619
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated",$link);
620
+                        break;
621
+                    case 'BILL_PAYED':
622
+                        $link ='<a href="' . $urlwithroot . '/compta/facture/card.php?facid='.$object->id . '">' . $newref . '</a>';
623
+                        $dir_output = $conf->facture->dir_output;
624
+                        $object_type = 'facture';
625
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed",$link);
626
+                        break;
627
+                    case 'ORDER_VALIDATE':
628
+                        $link = '<a href="' . $urlwithroot . '/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
629
+                        $dir_output = $conf->commande->dir_output;
630
+                        $object_type = 'order';
631
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextOrderValidated",$link);
632
+                        break;
633
+                    case 'PROPAL_VALIDATE':
634
+                        $link = '<a href="' . $urlwithroot . '/comm/propal/card.php?id='.$object->id . '">' . $newref . '</a>';
635
+                        $dir_output = $conf->propal->multidir_output[$object->entity];
636
+                        $object_type = 'propal';
637
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$link);
638
+                        break;
639
+                    case 'PROPAL_CLOSE_SIGNED':
640
+                        $link = '<a href="' . $urlwithroot . '/comm/propal/card.php?id='.$object->id . '">' . $newref . '</a>';
641
+                        $dir_output = $conf->propal->multidir_output[$object->entity];
642
+                        $object_type = 'propal';
643
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$link);
644
+                        break;
645
+                    case 'FICHINTER_ADD_CONTACT':
646
+                        $link = '<a href="' . $urlwithroot . '/fichinter/card.php?id='.$object->id . '">' . $newref . '</a>';
647
+                        $dir_output = $conf->facture->dir_output;
648
+                        $object_type = 'ficheinter';
649
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$link);
650
+                        break;
651
+                    case 'FICHINTER_VALIDATE':
652
+                        $link = '<a href="' . $urlwithroot . '/fichinter/card.php?id='.$object->id . '">' . $newref . '</a>';
653
+                        $dir_output = $conf->facture->dir_output;
654
+                        $object_type = 'ficheinter';
655
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated",$link);
656
+                        break;
657
+                    case 'ORDER_SUPPLIER_VALIDATE':
658
+                        $link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
659
+                        $dir_output = $conf->fournisseur->commande->dir_output;
660
+                        $object_type = 'order_supplier';
661
+                        $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
662
+                        $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$link,$user->getFullName($langs));
663
+                        $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
664
+                        break;
665
+                    case 'ORDER_SUPPLIER_APPROVE':
666
+                        $link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
667
+                        $dir_output = $conf->fournisseur->commande->dir_output;
668
+                        $object_type = 'order_supplier';
669
+                        $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
670
+                        $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$link,$user->getFullName($langs));
671
+                        $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
672
+                        break;
673
+                    case 'ORDER_SUPPLIER_APPROVE2':
674
+                        $link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
675
+                        $dir_output = $conf->fournisseur->commande->dir_output;
676
+                        $object_type = 'order_supplier';
677
+                        $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
678
+                        $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$link,$user->getFullName($langs));
679
+                        $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
680
+                        break;
681
+                    case 'ORDER_SUPPLIER_REFUSE':
682
+                        $link = '<a href="' . $urlwithroot . '/fourn/commande/card.php?id='.$object->id . '">' . $newref . '</a>';
683
+                        $dir_output = $conf->fournisseur->dir_output.'/commande/';
684
+                        $object_type = 'order_supplier';
685
+                        $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
686
+                        $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$link,$user->getFullName($langs));
687
+                        $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
688
+                        break;
689
+                    case 'SHIPPING_VALIDATE':
690
+                        $dir_output = $conf->expedition->dir_output.'/sending/';
691
+                        $object_type = 'order_supplier';
692
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
693
+                        break;
694
+                    case 'EXPENSE_REPORT_VALIDATE':
695
+                        $dir_output = $conf->expensereport->dir_output;
696
+                        $object_type = 'expensereport';
697
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
698
+                        break;
699
+                    case 'EXPENSE_REPORT_APPROVE':
700
+                        $dir_output = $conf->expensereport->dir_output;
701
+                        $object_type = 'expensereport';
702
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
703
+                        break;
704
+                    case 'HOLIDAY_VALIDATE':
705
+                        $dir_output = $conf->holiday->dir_output;
706
+                        $object_type = 'holiday';
707
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
708
+                        break;
709
+                    case 'HOLIDAY_APPROVE':
710
+                        $dir_output = $conf->holiday->dir_output;
711
+                        $object_type = 'holiday';
712
+                        $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
713
+                        break;
714
+                }
715
+                $ref = dol_sanitizeFileName($newref);
716
+                $pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
717
+                if (! dol_is_file($pdf_path))
718
+                {
719
+                    // We can't add PDF as it is not generated yet.
720
+                    $filepdf = '';
721
+                }
722
+                else
723
+                {
724
+                    $filepdf = $pdf_path;
725
+                }
726
+
727
+                $message = $langs->transnoentities("YouReceiveMailBecauseOfNotification",$application,$mysoc->name)."\n";
728
+                $message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n";
729
+                $message.= "\n";
730
+                $message.= $mesg;
731
+                //if ($link) $message.= "\n" . $urlwithroot . $link;	// link already added around the ref into the text
732
+
733
+                $message = nl2br($message);
734
+
735
+                // Replace keyword __SUPERVISOREMAIL__
736
+                if (preg_match('/__SUPERVISOREMAIL__/', $sendto))
737
+                {
738
+                    $newval='';
739
+                    if ($user->fk_user > 0)
740
+                    {
741
+                        $supervisoruser=new User($this->db);
742
+                        $supervisoruser->fetch($user->fk_user);
743
+                        if ($supervisoruser->email) $newval=trim(dolGetFirstLastname($supervisoruser->firstname, $supervisoruser->lastname).' <'.$supervisoruser->email.'>');
744
+                    }
745
+                    dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
746
+                    $sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
747
+                    $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
748
+                    $sendto = preg_replace('/^[\s,]+/', '', $sendto);	// Clean start of string
749
+                    $sendto = preg_replace('/[\s,]+$/', '', $sendto);	// Clean end of string
750
+                }
751
+
752
+                if ($sendto)
753
+                {
754
+                    $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list);
755
+                    $reshook=$hookmanager->executeHooks('formatNotificationMessage',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
756
+                    if (empty($reshook))
757
+                    {
758
+                        if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject'];
759
+                        if (! empty($hookmanager->resArray['message'])) $message.=$hookmanager->resArray['message'];
760
+                    }
761
+                    $mailfile = new CMailFile(
762
+                        $subject,
763
+                        $sendto,
764
+                        $replyto,
765
+                        $message,
766
+                        $filename_list,
767
+                        $mimetype_list,
768
+                        $mimefilename_list,
769
+                        '',
770
+                        '',
771
+                        0,
772
+                        1
773
+                    );
774
+
775
+                    if ($mailfile->sendfile())
776
+                    {
777
+                        $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, type_target, objet_type, objet_id, email)";
778
+                        $sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", null, 'email', 'tofixedemail', '".$object_type."', ".$object->id.", '".$this->db->escape($conf->global->$param)."')";
779
+                        if (! $this->db->query($sql))
780
+                        {
781
+                            dol_print_error($this->db);
782
+                        }
783
+                    }
784
+                    else
785
+                    {
786
+                        $error++;
787
+                        $this->errors[]=$mailfile->error;
788
+                    }
789
+                }
790
+            }
791
+        }
792
+
793
+        if (! $error) return $num;
794
+        else return -1 * $error;
795
+    }
796 796
 }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/dolgeoip.class.php 1 patch
Indentation   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -33,115 +33,115 @@
 block discarded – undo
33 33
  */
34 34
 class DolGeoIP
35 35
 {
36
-	var $gi;
36
+    var $gi;
37 37
 
38
-	/**
39
-	 * Constructor
40
-	 *
41
-	 * @param 	string	$type		'country' or 'city'
42
-	 * @param	string	$datfile	Data file
43
-	 */
44
-	function __construct($type,$datfile)
45
-	{
46
-		if ($type == 'country')
47
-		{
48
-		    // geoip may have been already included with PEAR
49
-		    if (! function_exists('geoip_country_code_by_name')) $res=include_once GEOIP_PATH.'geoip.inc';
50
-		}
51
-		else if ($type == 'city')
52
-		{
53
-		    // geoip may have been already included with PEAR
54
-		    if (! function_exists('geoip_country_code_by_name')) $res=include_once GEOIP_PATH.'geoipcity.inc';
55
-		}
56
-		else { print 'ErrorBadParameterInConstructor'; return 0; }
38
+    /**
39
+     * Constructor
40
+     *
41
+     * @param 	string	$type		'country' or 'city'
42
+     * @param	string	$datfile	Data file
43
+     */
44
+    function __construct($type,$datfile)
45
+    {
46
+        if ($type == 'country')
47
+        {
48
+            // geoip may have been already included with PEAR
49
+            if (! function_exists('geoip_country_code_by_name')) $res=include_once GEOIP_PATH.'geoip.inc';
50
+        }
51
+        else if ($type == 'city')
52
+        {
53
+            // geoip may have been already included with PEAR
54
+            if (! function_exists('geoip_country_code_by_name')) $res=include_once GEOIP_PATH.'geoipcity.inc';
55
+        }
56
+        else { print 'ErrorBadParameterInConstructor'; return 0; }
57 57
 
58
-		// Here, function exists (embedded into PHP or exists because we made include)
59
-		if (empty($type) || empty($datfile))
60
-		{
61
-			$this->errorlabel='Constructor was called with no datafile parameter';
62
-			dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
63
-			return 0;
64
-		}
65
-		if (! file_exists($datfile) || ! is_readable($datfile))
66
-		{
67
-			$this->error='ErrorGeoIPClassNotInitialized';
68
-			$this->errorlabel="Datafile ".$datfile." not found";
69
-			dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
70
-			return 0;
71
-		}
58
+        // Here, function exists (embedded into PHP or exists because we made include)
59
+        if (empty($type) || empty($datfile))
60
+        {
61
+            $this->errorlabel='Constructor was called with no datafile parameter';
62
+            dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
63
+            return 0;
64
+        }
65
+        if (! file_exists($datfile) || ! is_readable($datfile))
66
+        {
67
+            $this->error='ErrorGeoIPClassNotInitialized';
68
+            $this->errorlabel="Datafile ".$datfile." not found";
69
+            dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
70
+            return 0;
71
+        }
72 72
 
73
-		if (function_exists('geoip_open'))
74
-		{
75
-			$this->gi = geoip_open($datfile,GEOIP_STANDARD);
76
-		}
77
-		else
78
-		{
79
-		    $this->gi = 'NOGI';    // We are using embedded php geoip functions
80
-		    //print 'function_exists(geoip_country_code_by_name))='.function_exists('geoip_country_code_by_name');
81
-		    //print geoip_database_info();
82
-		}
83
-	}
73
+        if (function_exists('geoip_open'))
74
+        {
75
+            $this->gi = geoip_open($datfile,GEOIP_STANDARD);
76
+        }
77
+        else
78
+        {
79
+            $this->gi = 'NOGI';    // We are using embedded php geoip functions
80
+            //print 'function_exists(geoip_country_code_by_name))='.function_exists('geoip_country_code_by_name');
81
+            //print geoip_database_info();
82
+        }
83
+    }
84 84
 
85
-	/**
86
-	 * Return in lower case the country code from an ip
87
-	 *
88
-	 * @param	string	$ip		IP to scan
89
-	 * @return	string			Country code (two letters)
90
-	 */
91
-	function getCountryCodeFromIP($ip)
92
-	{
93
-		if (empty($this->gi))
94
-		{
95
-			return '';
96
-		}
97
-		if ($this->gi == 'NOGI')
98
-		{
99
-		    // geoip_country_code_by_addr does not exists
100
-    		return strtolower(geoip_country_code_by_name($ip));
101
-		}
102
-		else
103
-		{
104
-		    if (! function_exists('geoip_country_code_by_addr')) return strtolower(geoip_country_code_by_name($this->gi, $ip));
105
-		    return strtolower(geoip_country_code_by_addr($this->gi, $ip));
106
-		}
107
-	}
85
+    /**
86
+     * Return in lower case the country code from an ip
87
+     *
88
+     * @param	string	$ip		IP to scan
89
+     * @return	string			Country code (two letters)
90
+     */
91
+    function getCountryCodeFromIP($ip)
92
+    {
93
+        if (empty($this->gi))
94
+        {
95
+            return '';
96
+        }
97
+        if ($this->gi == 'NOGI')
98
+        {
99
+            // geoip_country_code_by_addr does not exists
100
+            return strtolower(geoip_country_code_by_name($ip));
101
+        }
102
+        else
103
+        {
104
+            if (! function_exists('geoip_country_code_by_addr')) return strtolower(geoip_country_code_by_name($this->gi, $ip));
105
+            return strtolower(geoip_country_code_by_addr($this->gi, $ip));
106
+        }
107
+    }
108 108
 
109
-	/**
110
-	 * Return in lower case the country code from a host name
111
-	 *
112
-	 * @param	string	$name	FQN of host (example: myserver.xyz.com)
113
-	 * @return	string			Country code (two letters)
114
-	 */
115
-	function getCountryCodeFromName($name)
116
-	{
117
-		if (empty($this->gi))
118
-		{
119
-			return '';
120
-		}
121
-		return geoip_country_code_by_name($this->gi, $name);
122
-	}
109
+    /**
110
+     * Return in lower case the country code from a host name
111
+     *
112
+     * @param	string	$name	FQN of host (example: myserver.xyz.com)
113
+     * @return	string			Country code (two letters)
114
+     */
115
+    function getCountryCodeFromName($name)
116
+    {
117
+        if (empty($this->gi))
118
+        {
119
+            return '';
120
+        }
121
+        return geoip_country_code_by_name($this->gi, $name);
122
+    }
123 123
 
124
-	/**
125
-	 * Return verion of data file
126
-	 *
127
-	 * @return	string		Version of datafile
128
-	 */
129
-	function getVersion()
130
-	{
131
-	    if ($this->gi == 'NOGI') return geoip_database_info();
132
-		return 'Not available (not using PHP internal geo functions)';
133
-	}
124
+    /**
125
+     * Return verion of data file
126
+     *
127
+     * @return	string		Version of datafile
128
+     */
129
+    function getVersion()
130
+    {
131
+        if ($this->gi == 'NOGI') return geoip_database_info();
132
+        return 'Not available (not using PHP internal geo functions)';
133
+    }
134 134
 
135
-	/**
136
-	 * Close geoip object
137
-	 *
138
-	 * @return	void
139
-	 */
140
-	function close()
141
-	{
142
-	    if (function_exists('geoip_close'))    // With some geoip with PEAR, geoip_close function may not exists
143
-	    {
144
-	        geoip_close($this->gi);
145
-	    }
146
-	}
135
+    /**
136
+     * Close geoip object
137
+     *
138
+     * @return	void
139
+     */
140
+    function close()
141
+    {
142
+        if (function_exists('geoip_close'))    // With some geoip with PEAR, geoip_close function may not exists
143
+        {
144
+            geoip_close($this->gi);
145
+        }
146
+    }
147 147
 }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/html.formfile.class.php 1 patch
Indentation   +1761 added lines, -1761 removed lines patch added patch discarded remove patch
@@ -34,312 +34,312 @@  discard block
 block discarded – undo
34 34
  */
35 35
 class FormFile
36 36
 {
37
-	private $db;
37
+    private $db;
38 38
 
39
-	/**
40
-	 * @var string Error code (or message)
41
-	 */
42
-	public $error;
39
+    /**
40
+     * @var string Error code (or message)
41
+     */
42
+    public $error;
43 43
 
44
-	public $numoffiles;
45
-	public $infofiles;			// Used to return informations by function getDocumentsLink
44
+    public $numoffiles;
45
+    public $infofiles;			// Used to return informations by function getDocumentsLink
46 46
 
47 47
 
48
-	/**
49
-	 *	Constructor
50
-	 *
51
-	 *  @param		DoliDB		$db      Database handler
52
-	 */
53
-	function __construct($db)
54
-	{
55
-		$this->db = $db;
56
-		$this->numoffiles=0;
57
-	}
48
+    /**
49
+     *	Constructor
50
+     *
51
+     *  @param		DoliDB		$db      Database handler
52
+     */
53
+    function __construct($db)
54
+    {
55
+        $this->db = $db;
56
+        $this->numoffiles=0;
57
+    }
58 58
 
59 59
 
60 60
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
61
-	/**
62
-	 *  Show form to upload a new file.
63
-	 *
64
-	 *  @param  string		$url			Url
65
-	 *  @param  string		$title			Title zone (Title or '' or 'none')
66
-	 *  @param  int			$addcancel		1=Add 'Cancel' button
67
-	 *	@param	int			$sectionid		If upload must be done inside a particular ECM section (is sectionid defined, sectiondir must not be)
68
-	 * 	@param	int			$perm			Value of permission to allow upload
69
-	 *  @param  int			$size          		Length of input file area. Deprecated.
70
-	 *  @param	Object		$object			Object to use (when attachment is done on an element)
71
-	 *  @param	string		$options		Add an option column
72
-	 *  @param	integer		$useajax		Use fileupload ajax (0=never, 1=if enabled, 2=always whatever is option). @deprecated 2 should never be used and if 1 is used, option should no be enabled.
73
-	 *  @param	string		$savingdocmask		Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__'
74
-	 *  @param	integer		$linkfiles		1=Also add form to link files, 0=Do not show form to link files
75
-	 *  @param	string		$htmlname		Name and id of HTML form ('formuserfile' by default, 'formuserfileecm' when used to upload a file in ECM)
76
-	 *  @param	string		$accept			Specifies the types of files accepted (This is not a security check but an user interface facility. eg '.pdf,image/*' or '.png,.jpg' or 'video/*')
77
-	 *	@param	string		$sectiondir		If upload must be done inside a particular directory (is sectiondir defined, sectionid must not be)
78
-	 * 	@return	int							<0 if KO, >0 if OK
79
-	 */
80
-	function form_attach_new_file($url, $title='', $addcancel=0, $sectionid=0, $perm=1, $size=50, $object='', $options='', $useajax=1, $savingdocmask='', $linkfiles=1, $htmlname='formuserfile', $accept='', $sectiondir='')
81
-	{
61
+    /**
62
+     *  Show form to upload a new file.
63
+     *
64
+     *  @param  string		$url			Url
65
+     *  @param  string		$title			Title zone (Title or '' or 'none')
66
+     *  @param  int			$addcancel		1=Add 'Cancel' button
67
+     *	@param	int			$sectionid		If upload must be done inside a particular ECM section (is sectionid defined, sectiondir must not be)
68
+     * 	@param	int			$perm			Value of permission to allow upload
69
+     *  @param  int			$size          		Length of input file area. Deprecated.
70
+     *  @param	Object		$object			Object to use (when attachment is done on an element)
71
+     *  @param	string		$options		Add an option column
72
+     *  @param	integer		$useajax		Use fileupload ajax (0=never, 1=if enabled, 2=always whatever is option). @deprecated 2 should never be used and if 1 is used, option should no be enabled.
73
+     *  @param	string		$savingdocmask		Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__'
74
+     *  @param	integer		$linkfiles		1=Also add form to link files, 0=Do not show form to link files
75
+     *  @param	string		$htmlname		Name and id of HTML form ('formuserfile' by default, 'formuserfileecm' when used to upload a file in ECM)
76
+     *  @param	string		$accept			Specifies the types of files accepted (This is not a security check but an user interface facility. eg '.pdf,image/*' or '.png,.jpg' or 'video/*')
77
+     *	@param	string		$sectiondir		If upload must be done inside a particular directory (is sectiondir defined, sectionid must not be)
78
+     * 	@return	int							<0 if KO, >0 if OK
79
+     */
80
+    function form_attach_new_file($url, $title='', $addcancel=0, $sectionid=0, $perm=1, $size=50, $object='', $options='', $useajax=1, $savingdocmask='', $linkfiles=1, $htmlname='formuserfile', $accept='', $sectiondir='')
81
+    {
82 82
         // phpcs:enable
83
-		global $conf,$langs, $hookmanager;
84
-		$hookmanager->initHooks(array('formfile'));
85
-
86
-
87
-		if (! empty($conf->browser->layout) && $conf->browser->layout != 'classic') $useajax=0;
88
-
89
-		if ((! empty($conf->global->MAIN_USE_JQUERY_FILEUPLOAD) && $useajax) || ($useajax==2))
90
-		{
91
-			// TODO: Check this works with 2 forms on same page
92
-			// TODO: Check this works with GED module, otherwise, force useajax to 0
93
-			// TODO: This does not support option savingdocmask
94
-			// TODO: This break feature to upload links too
95
-			return $this->_formAjaxFileUpload($object);
96
-		}
97
-		else
98
-	   	{
99
-			//If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed
100
-			if (!$perm && !empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) {
101
-				return 1;
102
-			}
103
-
104
-			$maxlength=$size;
105
-
106
-			$out = "\n\n<!-- Start form attach new file -->\n";
107
-
108
-			if (empty($title)) $title=$langs->trans("AttachANewFile");
109
-			if ($title != 'none') $out.=load_fiche_titre($title, null, null);
110
-
111
-			$out .= '<form name="'.$htmlname.'" id="'.$htmlname.'" action="'.$url.'" enctype="multipart/form-data" method="POST">';
112
-			$out .= '<input type="hidden" id="'.$htmlname.'_section_dir" name="section_dir" value="'.$sectiondir.'">';
113
-			$out .= '<input type="hidden" id="'.$htmlname.'_section_id"  name="section_id" value="'.$sectionid.'">';
114
-			$out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
115
-
116
-			$out .= '<table width="100%" class="nobordernopadding">';
117
-			$out .= '<tr>';
118
-
119
-			if (! empty($options)) $out .= '<td>'.$options.'</td>';
120
-
121
-			$out .= '<td class="valignmiddle nowrap">';
122
-
123
-			$max=$conf->global->MAIN_UPLOAD_DOC;		// En Kb
124
-			$maxphp=@ini_get('upload_max_filesize');	// En inconnu
125
-			if (preg_match('/k$/i',$maxphp)) $maxphp=$maxphp*1;
126
-			if (preg_match('/m$/i',$maxphp)) $maxphp=$maxphp*1024;
127
-			if (preg_match('/g$/i',$maxphp)) $maxphp=$maxphp*1024*1024;
128
-			if (preg_match('/t$/i',$maxphp)) $maxphp=$maxphp*1024*1024*1024;
129
-			// Now $max and $maxphp are in Kb
130
-			$maxmin = $max;
131
-			if ($maxphp > 0) $maxmin=min($max,$maxphp);
132
-
133
-			if ($maxmin > 0)
134
-			{
135
-				// MAX_FILE_SIZE doit précéder le champ input de type file
136
-				$out .= '<input type="hidden" name="max_file_size" value="'.($maxmin*1024).'">';
137
-			}
138
-
139
-			$out .= '<input class="flat minwidth400" type="file"';
140
-			$out .= ((! empty($conf->global->MAIN_DISABLE_MULTIPLE_FILEUPLOAD) || $conf->browser->layout != 'classic')?' name="userfile"':' name="userfile[]" multiple');
141
-			$out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
142
-			$out .= (!empty($accept)?' accept="'.$accept.'"':' accept=""');
143
-			$out .= '>';
144
-			$out .= ' ';
145
-			$out .= '<input type="submit" class="button" name="sendit" value="'.$langs->trans("Upload").'"';
146
-			$out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
147
-			$out .= '>';
148
-
149
-			if ($addcancel)
150
-			{
151
-				$out .= ' &nbsp; ';
152
-				$out .= '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
153
-			}
154
-
155
-			if (! empty($conf->global->MAIN_UPLOAD_DOC))
156
-			{
157
-				if ($perm)
158
-				{
159
-					$langs->load('other');
160
-					$out .= ' ';
161
-					$out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup",$max,$maxphp),1);
162
-				}
163
-			}
164
-			else
165
-			{
166
-				$out .= ' ('.$langs->trans("UploadDisabled").')';
167
-			}
168
-			$out .= "</td></tr>";
169
-
170
-			if ($savingdocmask)
171
-			{
172
-				$out .= '<tr>';
173
-   				if (! empty($options)) $out .= '<td>'.$options.'</td>';
174
-				$out .= '<td valign="middle" class="nowrap">';
175
-				$out .= '<input type="checkbox" checked class="savingdocmask" name="savingdocmask" value="'.dol_escape_js($savingdocmask).'"> '.$langs->trans("SaveUploadedFileWithMask", preg_replace('/__file__/',$langs->transnoentitiesnoconv("OriginFileName"),$savingdocmask), $langs->transnoentitiesnoconv("OriginFileName"));
176
-				$out .= '</td>';
177
-				$out .= '</tr>';
178
-			}
179
-
180
-			$out .= "</table>";
181
-
182
-			$out .= '</form>';
183
-			if (empty($sectionid)) $out .= '<br>';
184
-
185
-			$out .= "\n<!-- End form attach new file -->\n";
186
-
187
-			if ($linkfiles)
188
-			{
189
-				$out .= "\n<!-- Start form link new url -->\n";
190
-				$langs->load('link');
191
-				$title = $langs->trans("LinkANewFile");
192
-				$out .= load_fiche_titre($title, null, null);
193
-				$out .= '<form name="'.$htmlname.'_link" id="'.$htmlname.'_link" action="'.$url.'" method="POST">';
194
-				$out .= '<input type="hidden" id="'.$htmlname.'_link_section_dir" name="link_section_dir" value="">';
195
-				$out .= '<input type="hidden" id="'.$htmlname.'_link_section_id"  name="link_section_id" value="'.$sectionid.'">';
196
-				$out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
197
-
198
-				$out .= '<div class="valignmiddle" >';
199
-				$out .= '<div class="inline-block" style="padding-right: 10px;">';
200
-				if (! empty($conf->global->OPTIMIZEFORTEXTBROWSER)) $out .= '<label for="link">'.$langs->trans("URLToLink") . ':</label> ';
201
-				$out .= '<input type="text" name="link" class="flat minwidth400imp" id="link" placeholder="'.dol_escape_htmltag($langs->trans("URLToLink")).'">';
202
-				$out .= '</div>';
203
-				$out .= '<div class="inline-block" style="padding-right: 10px;">';
204
-				if (! empty($conf->global->OPTIMIZEFORTEXTBROWSER)) $out .= '<label for="label">'.$langs->trans("Label") . ':</label> ';
205
-				$out .= '<input type="text" class="flat" name="label" id="label" placeholder="'.dol_escape_htmltag($langs->trans("Label")).'">';
206
-				$out .= '<input type="hidden" name="objecttype" value="' . $object->element . '">';
207
-				$out .= '<input type="hidden" name="objectid" value="' . $object->id . '">';
208
-				$out .= '</div>';
209
-				$out .= '<div class="inline-block" style="padding-right: 10px;">';
210
-				$out .= '<input type="submit" class="button" name="linkit" value="'.$langs->trans("ToLink").'"';
211
-				$out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
212
-				$out .= '>';
213
-				$out .= '</div>';
214
-				$out .= '</div>';
215
-				$out .= '<div class="clearboth"></div>';
216
-				$out .= '</form><br>';
217
-
218
-				$out .= "\n<!-- End form link new url -->\n";
219
-			}
220
-
221
-			$parameters = array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''), 'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''), 'url'=>$url, 'perm'=>$perm);
222
-			$res = $hookmanager->executeHooks('formattachOptions',$parameters,$object);
223
-			if (empty($res))
224
-			{
225
-				print '<div class="attacharea attacharea'.$htmlname.'">';
226
-				print $out;
227
-				print '</div>';
228
-			}
229
-			print $hookmanager->resPrint;
230
-
231
-			return 1;
232
-		}
233
-	}
83
+        global $conf,$langs, $hookmanager;
84
+        $hookmanager->initHooks(array('formfile'));
85
+
86
+
87
+        if (! empty($conf->browser->layout) && $conf->browser->layout != 'classic') $useajax=0;
88
+
89
+        if ((! empty($conf->global->MAIN_USE_JQUERY_FILEUPLOAD) && $useajax) || ($useajax==2))
90
+        {
91
+            // TODO: Check this works with 2 forms on same page
92
+            // TODO: Check this works with GED module, otherwise, force useajax to 0
93
+            // TODO: This does not support option savingdocmask
94
+            // TODO: This break feature to upload links too
95
+            return $this->_formAjaxFileUpload($object);
96
+        }
97
+        else
98
+            {
99
+            //If there is no permission and the option to hide unauthorized actions is enabled, then nothing is printed
100
+            if (!$perm && !empty($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)) {
101
+                return 1;
102
+            }
103
+
104
+            $maxlength=$size;
105
+
106
+            $out = "\n\n<!-- Start form attach new file -->\n";
107
+
108
+            if (empty($title)) $title=$langs->trans("AttachANewFile");
109
+            if ($title != 'none') $out.=load_fiche_titre($title, null, null);
110
+
111
+            $out .= '<form name="'.$htmlname.'" id="'.$htmlname.'" action="'.$url.'" enctype="multipart/form-data" method="POST">';
112
+            $out .= '<input type="hidden" id="'.$htmlname.'_section_dir" name="section_dir" value="'.$sectiondir.'">';
113
+            $out .= '<input type="hidden" id="'.$htmlname.'_section_id"  name="section_id" value="'.$sectionid.'">';
114
+            $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
115
+
116
+            $out .= '<table width="100%" class="nobordernopadding">';
117
+            $out .= '<tr>';
118
+
119
+            if (! empty($options)) $out .= '<td>'.$options.'</td>';
120
+
121
+            $out .= '<td class="valignmiddle nowrap">';
122
+
123
+            $max=$conf->global->MAIN_UPLOAD_DOC;		// En Kb
124
+            $maxphp=@ini_get('upload_max_filesize');	// En inconnu
125
+            if (preg_match('/k$/i',$maxphp)) $maxphp=$maxphp*1;
126
+            if (preg_match('/m$/i',$maxphp)) $maxphp=$maxphp*1024;
127
+            if (preg_match('/g$/i',$maxphp)) $maxphp=$maxphp*1024*1024;
128
+            if (preg_match('/t$/i',$maxphp)) $maxphp=$maxphp*1024*1024*1024;
129
+            // Now $max and $maxphp are in Kb
130
+            $maxmin = $max;
131
+            if ($maxphp > 0) $maxmin=min($max,$maxphp);
132
+
133
+            if ($maxmin > 0)
134
+            {
135
+                // MAX_FILE_SIZE doit précéder le champ input de type file
136
+                $out .= '<input type="hidden" name="max_file_size" value="'.($maxmin*1024).'">';
137
+            }
138
+
139
+            $out .= '<input class="flat minwidth400" type="file"';
140
+            $out .= ((! empty($conf->global->MAIN_DISABLE_MULTIPLE_FILEUPLOAD) || $conf->browser->layout != 'classic')?' name="userfile"':' name="userfile[]" multiple');
141
+            $out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
142
+            $out .= (!empty($accept)?' accept="'.$accept.'"':' accept=""');
143
+            $out .= '>';
144
+            $out .= ' ';
145
+            $out .= '<input type="submit" class="button" name="sendit" value="'.$langs->trans("Upload").'"';
146
+            $out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
147
+            $out .= '>';
148
+
149
+            if ($addcancel)
150
+            {
151
+                $out .= ' &nbsp; ';
152
+                $out .= '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
153
+            }
154
+
155
+            if (! empty($conf->global->MAIN_UPLOAD_DOC))
156
+            {
157
+                if ($perm)
158
+                {
159
+                    $langs->load('other');
160
+                    $out .= ' ';
161
+                    $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup",$max,$maxphp),1);
162
+                }
163
+            }
164
+            else
165
+            {
166
+                $out .= ' ('.$langs->trans("UploadDisabled").')';
167
+            }
168
+            $out .= "</td></tr>";
169
+
170
+            if ($savingdocmask)
171
+            {
172
+                $out .= '<tr>';
173
+                    if (! empty($options)) $out .= '<td>'.$options.'</td>';
174
+                $out .= '<td valign="middle" class="nowrap">';
175
+                $out .= '<input type="checkbox" checked class="savingdocmask" name="savingdocmask" value="'.dol_escape_js($savingdocmask).'"> '.$langs->trans("SaveUploadedFileWithMask", preg_replace('/__file__/',$langs->transnoentitiesnoconv("OriginFileName"),$savingdocmask), $langs->transnoentitiesnoconv("OriginFileName"));
176
+                $out .= '</td>';
177
+                $out .= '</tr>';
178
+            }
179
+
180
+            $out .= "</table>";
181
+
182
+            $out .= '</form>';
183
+            if (empty($sectionid)) $out .= '<br>';
184
+
185
+            $out .= "\n<!-- End form attach new file -->\n";
186
+
187
+            if ($linkfiles)
188
+            {
189
+                $out .= "\n<!-- Start form link new url -->\n";
190
+                $langs->load('link');
191
+                $title = $langs->trans("LinkANewFile");
192
+                $out .= load_fiche_titre($title, null, null);
193
+                $out .= '<form name="'.$htmlname.'_link" id="'.$htmlname.'_link" action="'.$url.'" method="POST">';
194
+                $out .= '<input type="hidden" id="'.$htmlname.'_link_section_dir" name="link_section_dir" value="">';
195
+                $out .= '<input type="hidden" id="'.$htmlname.'_link_section_id"  name="link_section_id" value="'.$sectionid.'">';
196
+                $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
197
+
198
+                $out .= '<div class="valignmiddle" >';
199
+                $out .= '<div class="inline-block" style="padding-right: 10px;">';
200
+                if (! empty($conf->global->OPTIMIZEFORTEXTBROWSER)) $out .= '<label for="link">'.$langs->trans("URLToLink") . ':</label> ';
201
+                $out .= '<input type="text" name="link" class="flat minwidth400imp" id="link" placeholder="'.dol_escape_htmltag($langs->trans("URLToLink")).'">';
202
+                $out .= '</div>';
203
+                $out .= '<div class="inline-block" style="padding-right: 10px;">';
204
+                if (! empty($conf->global->OPTIMIZEFORTEXTBROWSER)) $out .= '<label for="label">'.$langs->trans("Label") . ':</label> ';
205
+                $out .= '<input type="text" class="flat" name="label" id="label" placeholder="'.dol_escape_htmltag($langs->trans("Label")).'">';
206
+                $out .= '<input type="hidden" name="objecttype" value="' . $object->element . '">';
207
+                $out .= '<input type="hidden" name="objectid" value="' . $object->id . '">';
208
+                $out .= '</div>';
209
+                $out .= '<div class="inline-block" style="padding-right: 10px;">';
210
+                $out .= '<input type="submit" class="button" name="linkit" value="'.$langs->trans("ToLink").'"';
211
+                $out .= (empty($conf->global->MAIN_UPLOAD_DOC) || empty($perm)?' disabled':'');
212
+                $out .= '>';
213
+                $out .= '</div>';
214
+                $out .= '</div>';
215
+                $out .= '<div class="clearboth"></div>';
216
+                $out .= '</form><br>';
217
+
218
+                $out .= "\n<!-- End form link new url -->\n";
219
+            }
220
+
221
+            $parameters = array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''), 'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''), 'url'=>$url, 'perm'=>$perm);
222
+            $res = $hookmanager->executeHooks('formattachOptions',$parameters,$object);
223
+            if (empty($res))
224
+            {
225
+                print '<div class="attacharea attacharea'.$htmlname.'">';
226
+                print $out;
227
+                print '</div>';
228
+            }
229
+            print $hookmanager->resPrint;
230
+
231
+            return 1;
232
+        }
233
+    }
234 234
 
235 235
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
236
-	/**
237
-	 *      Show the box with list of available documents for object
238
-	 *
239
-	 *      @param      string				$modulepart         propal, facture, facture_fourn, ...
240
-	 *      @param      string				$modulesubdir       Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
241
-	 *      @param      string				$filedir            Directory to scan
242
-	 *      @param      string				$urlsource          Url of origin page (for return)
243
-	 *      @param      int					$genallowed         Generation is allowed (1/0 or array of formats)
244
-	 *      @param      int					$delallowed         Remove is allowed (1/0)
245
-	 *      @param      string				$modelselected      Model to preselect by default
246
-	 *      @param      integer				$allowgenifempty	Show warning if no model activated
247
-	 *      @param      integer				$forcenomultilang	Do not show language option (even if MAIN_MULTILANGS defined)
248
-	 *      @param      int					$iconPDF            Show only PDF icon with link (1/0)
249
-	 * 		@param		int					$notused	        Not used
250
-	 * 		@param		integer				$noform				Do not output html form tags
251
-	 * 		@param		string				$param				More param on http links
252
-	 * 		@param		string				$title				Title to show on top of form
253
-	 * 		@param		string				$buttonlabel		Label on submit button
254
-	 * 		@param		string				$codelang			Default language code to use on lang combo box if multilang is enabled
255
-	 * 		@return		int										<0 if KO, number of shown files if OK
256
-	 *      @deprecated                                         Use print xxx->showdocuments() instead.
257
-	 */
258
-	function show_documents($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='')
259
-	{
236
+    /**
237
+     *      Show the box with list of available documents for object
238
+     *
239
+     *      @param      string				$modulepart         propal, facture, facture_fourn, ...
240
+     *      @param      string				$modulesubdir       Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
241
+     *      @param      string				$filedir            Directory to scan
242
+     *      @param      string				$urlsource          Url of origin page (for return)
243
+     *      @param      int					$genallowed         Generation is allowed (1/0 or array of formats)
244
+     *      @param      int					$delallowed         Remove is allowed (1/0)
245
+     *      @param      string				$modelselected      Model to preselect by default
246
+     *      @param      integer				$allowgenifempty	Show warning if no model activated
247
+     *      @param      integer				$forcenomultilang	Do not show language option (even if MAIN_MULTILANGS defined)
248
+     *      @param      int					$iconPDF            Show only PDF icon with link (1/0)
249
+     * 		@param		int					$notused	        Not used
250
+     * 		@param		integer				$noform				Do not output html form tags
251
+     * 		@param		string				$param				More param on http links
252
+     * 		@param		string				$title				Title to show on top of form
253
+     * 		@param		string				$buttonlabel		Label on submit button
254
+     * 		@param		string				$codelang			Default language code to use on lang combo box if multilang is enabled
255
+     * 		@return		int										<0 if KO, number of shown files if OK
256
+     *      @deprecated                                         Use print xxx->showdocuments() instead.
257
+     */
258
+    function show_documents($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='')
259
+    {
260 260
         // phpcs:enable
261
-		$this->numoffiles=0;
262
-		print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$notused,$noform,$param,$title,$buttonlabel,$codelang);
263
-		return $this->numoffiles;
264
-	}
265
-
266
-	/**
267
-	 *      Return a string to show the box with list of available documents for object.
268
-	 *      This also set the property $this->numoffiles
269
-	 *
270
-	 *      @param      string				$modulepart         Module the files are related to ('propal', 'facture', 'facture_fourn', 'mymodule', 'mymodule_temp', ...)
271
-	 *      @param      string				$modulesubdir       Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
272
-	 *      @param      string				$filedir            Directory to scan
273
-	 *      @param      string				$urlsource          Url of origin page (for return)
274
-	 *      @param      int					$genallowed         Generation is allowed (1/0 or array list of templates)
275
-	 *      @param      int					$delallowed         Remove is allowed (1/0)
276
-	 *      @param      string				$modelselected      Model to preselect by default
277
-	 *      @param      integer				$allowgenifempty	Allow generation even if list of template ($genallowed) is empty (show however a warning)
278
-	 *      @param      integer				$forcenomultilang	Do not show language option (even if MAIN_MULTILANGS defined)
279
-	 *      @param      int					$iconPDF            Deprecated, see getDocumentsLink
280
-	 * 		@param		int					$notused	        Not used
281
-	 * 		@param		integer				$noform				Do not output html form tags
282
-	 * 		@param		string				$param				More param on http links
283
-	 * 		@param		string				$title				Title to show on top of form
284
-	 * 		@param		string				$buttonlabel		Label on submit button
285
-	 * 		@param		string				$codelang			Default language code to use on lang combo box if multilang is enabled
286
-	 * 		@param		string				$morepicto			Add more HTML content into cell with picto
287
-	 *      @param      Object              $object             Object when method is called from an object card.
288
-	 *      @param		int					$hideifempty		Hide section of generated files if there is no file
289
-	 * 		@return		string              					Output string with HTML array of documents (might be empty string)
290
-	 */
291
-	function showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$morepicto='',$object=null,$hideifempty=0)
292
-	{
293
-		// Deprecation warning
294
-		if (! empty($iconPDF)) {
295
-			dol_syslog(__METHOD__ . ": passing iconPDF parameter is deprecated", LOG_WARNING);
296
-		}
297
-
298
-		global $langs, $conf, $user, $hookmanager;
299
-		global $form;
300
-
301
-		if (! is_object($form)) $form=new Form($this->db);
302
-
303
-		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
304
-
305
-		// For backward compatibility
306
-		if (! empty($iconPDF)) {
307
-			return $this->getDocumentsLink($modulepart, $modulesubdir, $filedir);
308
-		}
309
-
310
-		// Add entity in $param
311
-		$param.= 'entity='.(!empty($object->entity)?$object->entity:$conf->entity);
312
-
313
-		$printer=0;
314
-		if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport','livraison')))	// The direct print feature is implemented only for such elements
315
-		{
316
-			$printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
317
-		}
318
-
319
-		$hookmanager->initHooks(array('formfile'));
320
-
321
-		// Get list of files
322
-		$file_list=null;
323
-		if (! empty($filedir))
324
-		{
325
-			$file_list=dol_dir_list($filedir,'files',0,'','(\.meta|_preview.*.*\.png)$','date',SORT_DESC);
326
-		}
327
-		if ($hideifempty && empty($file_list)) return '';
328
-
329
-		$out='';
330
-		$forname='builddoc';
331
-		$headershown=0;
332
-		$showempty=0;
333
-		$i=0;
334
-
335
-		$out.= "\n".'<!-- Start show_document -->'."\n";
336
-		//print 'filedir='.$filedir;
337
-
338
-		if (preg_match('/massfilesarea_/', $modulepart))
339
-		{
340
-			$out.='<div id="show_files"><br></div>'."\n";
341
-			$title=$langs->trans("MassFilesArea").' <a href="" id="togglemassfilesarea" ref="shown">('.$langs->trans("Hide").')</a>';
342
-			$title.='<script type="text/javascript" language="javascript">
261
+        $this->numoffiles=0;
262
+        print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$notused,$noform,$param,$title,$buttonlabel,$codelang);
263
+        return $this->numoffiles;
264
+    }
265
+
266
+    /**
267
+     *      Return a string to show the box with list of available documents for object.
268
+     *      This also set the property $this->numoffiles
269
+     *
270
+     *      @param      string				$modulepart         Module the files are related to ('propal', 'facture', 'facture_fourn', 'mymodule', 'mymodule_temp', ...)
271
+     *      @param      string				$modulesubdir       Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
272
+     *      @param      string				$filedir            Directory to scan
273
+     *      @param      string				$urlsource          Url of origin page (for return)
274
+     *      @param      int					$genallowed         Generation is allowed (1/0 or array list of templates)
275
+     *      @param      int					$delallowed         Remove is allowed (1/0)
276
+     *      @param      string				$modelselected      Model to preselect by default
277
+     *      @param      integer				$allowgenifempty	Allow generation even if list of template ($genallowed) is empty (show however a warning)
278
+     *      @param      integer				$forcenomultilang	Do not show language option (even if MAIN_MULTILANGS defined)
279
+     *      @param      int					$iconPDF            Deprecated, see getDocumentsLink
280
+     * 		@param		int					$notused	        Not used
281
+     * 		@param		integer				$noform				Do not output html form tags
282
+     * 		@param		string				$param				More param on http links
283
+     * 		@param		string				$title				Title to show on top of form
284
+     * 		@param		string				$buttonlabel		Label on submit button
285
+     * 		@param		string				$codelang			Default language code to use on lang combo box if multilang is enabled
286
+     * 		@param		string				$morepicto			Add more HTML content into cell with picto
287
+     *      @param      Object              $object             Object when method is called from an object card.
288
+     *      @param		int					$hideifempty		Hide section of generated files if there is no file
289
+     * 		@return		string              					Output string with HTML array of documents (might be empty string)
290
+     */
291
+    function showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$morepicto='',$object=null,$hideifempty=0)
292
+    {
293
+        // Deprecation warning
294
+        if (! empty($iconPDF)) {
295
+            dol_syslog(__METHOD__ . ": passing iconPDF parameter is deprecated", LOG_WARNING);
296
+        }
297
+
298
+        global $langs, $conf, $user, $hookmanager;
299
+        global $form;
300
+
301
+        if (! is_object($form)) $form=new Form($this->db);
302
+
303
+        include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
304
+
305
+        // For backward compatibility
306
+        if (! empty($iconPDF)) {
307
+            return $this->getDocumentsLink($modulepart, $modulesubdir, $filedir);
308
+        }
309
+
310
+        // Add entity in $param
311
+        $param.= 'entity='.(!empty($object->entity)?$object->entity:$conf->entity);
312
+
313
+        $printer=0;
314
+        if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport','livraison')))	// The direct print feature is implemented only for such elements
315
+        {
316
+            $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
317
+        }
318
+
319
+        $hookmanager->initHooks(array('formfile'));
320
+
321
+        // Get list of files
322
+        $file_list=null;
323
+        if (! empty($filedir))
324
+        {
325
+            $file_list=dol_dir_list($filedir,'files',0,'','(\.meta|_preview.*.*\.png)$','date',SORT_DESC);
326
+        }
327
+        if ($hideifempty && empty($file_list)) return '';
328
+
329
+        $out='';
330
+        $forname='builddoc';
331
+        $headershown=0;
332
+        $showempty=0;
333
+        $i=0;
334
+
335
+        $out.= "\n".'<!-- Start show_document -->'."\n";
336
+        //print 'filedir='.$filedir;
337
+
338
+        if (preg_match('/massfilesarea_/', $modulepart))
339
+        {
340
+            $out.='<div id="show_files"><br></div>'."\n";
341
+            $title=$langs->trans("MassFilesArea").' <a href="" id="togglemassfilesarea" ref="shown">('.$langs->trans("Hide").')</a>';
342
+            $title.='<script type="text/javascript" language="javascript">
343 343
 				jQuery(document).ready(function() {
344 344
 					jQuery(\'#togglemassfilesarea\').click(function() {
345 345
 						if (jQuery(\'#togglemassfilesarea\').attr(\'ref\') == "shown")
@@ -358,1489 +358,1489 @@  discard block
 block discarded – undo
358 358
 					});
359 359
 				});
360 360
 				</script>';
361
-		}
362
-
363
-		$titletoshow=$langs->trans("Documents");
364
-		if (! empty($title)) $titletoshow=$title;
365
-
366
-		// Show table
367
-		if ($genallowed)
368
-		{
369
-			$modellist=array();
370
-
371
-			if ($modulepart == 'company')
372
-			{
373
-				$showempty=1;
374
-				if (is_array($genallowed)) $modellist=$genallowed;
375
-				else
376
-				{
377
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php';
378
-					$modellist=ModeleThirdPartyDoc::liste_modeles($this->db);
379
-				}
380
-			}
381
-			else if ($modulepart == 'propal')
382
-			{
383
-				if (is_array($genallowed)) $modellist=$genallowed;
384
-				else
385
-				{
386
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
387
-					$modellist=ModelePDFPropales::liste_modeles($this->db);
388
-				}
389
-			}
390
-			else if ($modulepart == 'supplier_proposal')
391
-			{
392
-				if (is_array($genallowed)) $modellist=$genallowed;
393
-				else
394
-				{
395
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_proposal/modules_supplier_proposal.php';
396
-					$modellist=ModelePDFSupplierProposal::liste_modeles($this->db);
397
-				}
398
-			}
399
-			else if ($modulepart == 'commande')
400
-			{
401
-				if (is_array($genallowed)) $modellist=$genallowed;
402
-				else
403
-				{
404
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
405
-					$modellist=ModelePDFCommandes::liste_modeles($this->db);
406
-				}
407
-			}
408
-			elseif ($modulepart == 'expedition')
409
-			{
410
-				if (is_array($genallowed)) $modellist=$genallowed;
411
-				else
412
-				{
413
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php';
414
-					$modellist=ModelePDFExpedition::liste_modeles($this->db);
415
-				}
416
-			}
361
+        }
362
+
363
+        $titletoshow=$langs->trans("Documents");
364
+        if (! empty($title)) $titletoshow=$title;
365
+
366
+        // Show table
367
+        if ($genallowed)
368
+        {
369
+            $modellist=array();
370
+
371
+            if ($modulepart == 'company')
372
+            {
373
+                $showempty=1;
374
+                if (is_array($genallowed)) $modellist=$genallowed;
375
+                else
376
+                {
377
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php';
378
+                    $modellist=ModeleThirdPartyDoc::liste_modeles($this->db);
379
+                }
380
+            }
381
+            else if ($modulepart == 'propal')
382
+            {
383
+                if (is_array($genallowed)) $modellist=$genallowed;
384
+                else
385
+                {
386
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
387
+                    $modellist=ModelePDFPropales::liste_modeles($this->db);
388
+                }
389
+            }
390
+            else if ($modulepart == 'supplier_proposal')
391
+            {
392
+                if (is_array($genallowed)) $modellist=$genallowed;
393
+                else
394
+                {
395
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_proposal/modules_supplier_proposal.php';
396
+                    $modellist=ModelePDFSupplierProposal::liste_modeles($this->db);
397
+                }
398
+            }
399
+            else if ($modulepart == 'commande')
400
+            {
401
+                if (is_array($genallowed)) $modellist=$genallowed;
402
+                else
403
+                {
404
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
405
+                    $modellist=ModelePDFCommandes::liste_modeles($this->db);
406
+                }
407
+            }
408
+            elseif ($modulepart == 'expedition')
409
+            {
410
+                if (is_array($genallowed)) $modellist=$genallowed;
411
+                else
412
+                {
413
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php';
414
+                    $modellist=ModelePDFExpedition::liste_modeles($this->db);
415
+                }
416
+            }
417 417
             elseif ($modulepart == 'reception')
418 418
             {
419 419
                 if (is_array($genallowed)) $modellist=$genallowed;
420 420
                 else
421 421
                 {
422
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
423
-					$modellist = ModelePdfReception::liste_modeles($this->db);
424
-				}
425
-            }
426
-			elseif ($modulepart == 'livraison')
427
-			{
428
-				if (is_array($genallowed)) $modellist=$genallowed;
429
-				else
430
-				{
431
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/livraison/modules_livraison.php';
432
-					$modellist=ModelePDFDeliveryOrder::liste_modeles($this->db);
433
-				}
434
-			}
435
-			else if ($modulepart == 'ficheinter')
436
-			{
437
-				if (is_array($genallowed)) $modellist=$genallowed;
438
-				else
439
-				{
440
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/fichinter/modules_fichinter.php';
441
-					$modellist=ModelePDFFicheinter::liste_modeles($this->db);
442
-				}
443
-			}
444
-			elseif ($modulepart == 'facture')
445
-			{
446
-				if (is_array($genallowed)) $modellist=$genallowed;
447
-				else
448
-				{
449
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
450
-					$modellist=ModelePDFFactures::liste_modeles($this->db);
451
-				}
452
-			}
453
-			elseif ($modulepart == 'contract')
454
-			{
455
-				if (is_array($genallowed)) $modellist=$genallowed;
456
-				else
457
-				{
458
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php';
459
-					$modellist=ModelePDFContract::liste_modeles($this->db);
460
-				}
461
-			}
462
-			elseif ($modulepart == 'project')
463
-			{
464
-				if (is_array($genallowed)) $modellist=$genallowed;
465
-				else
466
-				{
467
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
468
-					$modellist=ModelePDFProjects::liste_modeles($this->db);
469
-				}
470
-			}
471
-			elseif ($modulepart == 'project_task')
472
-			{
473
-				if (is_array($genallowed)) $modellist=$genallowed;
474
-				else
475
-				{
476
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
477
-					$modellist=ModelePDFTask::liste_modeles($this->db);
478
-				}
479
-			}
480
-			elseif ($modulepart == 'product')
481
-			{
482
-				if (is_array($genallowed)) $modellist=$genallowed;
483
-				else
484
-				{
485
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php';
486
-					$modellist=ModelePDFProduct::liste_modeles($this->db);
487
-				}
488
-			}
489
-			elseif ($modulepart == 'product_batch')
490
-			{
491
-				if (is_array($genallowed)) $modellist=$genallowed;
492
-				else
493
-				{
494
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php';
495
-					$modellist=ModelePDFProductBatch::liste_modeles($this->db);
496
-				}
497
-			}
498
-			elseif ($modulepart == 'stock')
499
-			{
500
-				if (is_array($genallowed)) $modellist=$genallowed;
501
-				else
502
-				{
503
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.php';
504
-					$modellist=ModelePDFStock::liste_modeles($this->db);
505
-				}
506
-			}
507
-			elseif ($modulepart == 'movement')
508
-			{
509
-				if (is_array($genallowed)) $modellist=$genallowed;
510
-				else
511
-				{
512
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_movement.php';
513
-					$modellist=ModelePDFMovement::liste_modeles($this->db);
514
-				}
515
-			}
516
-			elseif ($modulepart == 'export')
517
-			{
518
-				if (is_array($genallowed)) $modellist=$genallowed;
519
-				else
520
-				{
521
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php';
522
-					$modellist=ModeleExports::liste_modeles($this->db);
523
-				}
524
-			}
525
-			else if ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order')
526
-			{
527
-				if (is_array($genallowed)) $modellist=$genallowed;
528
-				else
529
-				{
530
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
531
-					$modellist=ModelePDFSuppliersOrders::liste_modeles($this->db);
532
-				}
533
-			}
534
-			else if ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice')
535
-			{
536
-				if (is_array($genallowed)) $modellist=$genallowed;
537
-				else
538
-				{
539
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
540
-					$modellist=ModelePDFSuppliersInvoices::liste_modeles($this->db);
541
-				}
542
-			}
543
-			else if ($modulepart == 'supplier_payment')
544
-			{
545
-				if (is_array($genallowed)) $modellist=$genallowed;
546
-				else
547
-				{
548
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_payment/modules_supplier_payment.php';
549
-					$modellist=ModelePDFSuppliersPayments::liste_modeles($this->db);
550
-				}
551
-			}
552
-			else if ($modulepart == 'remisecheque')
553
-			{
554
-				if (is_array($genallowed)) $modellist=$genallowed;
555
-				else
556
-				{
557
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/cheque/modules_chequereceipts.php';
558
-					$modellist=ModeleChequeReceipts::liste_modeles($this->db);
559
-				}
560
-			}
561
-			elseif ($modulepart == 'donation')
562
-			{
563
-				if (is_array($genallowed)) $modellist=$genallowed;
564
-				else
565
-				{
566
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/dons/modules_don.php';
567
-					$modellist=ModeleDon::liste_modeles($this->db);
568
-				}
569
-			}
570
-			elseif ($modulepart == 'member')
571
-			{
572
-				if (is_array($genallowed)) $modellist=$genallowed;
573
-				else
574
-				{
575
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/member/modules_cards.php';
576
-					$modellist=ModelePDFCards::liste_modeles($this->db);
577
-				}
578
-			}
579
-			elseif ($modulepart == 'agenda' || $modulepart == 'actions')
580
-			{
581
-				if (is_array($genallowed)) $modellist=$genallowed;
582
-				else
583
-				{
584
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/action/modules_action.php';
585
-					$modellist=ModeleAction::liste_modeles($this->db);
586
-				}
587
-			}
588
-			else if ($modulepart == 'expensereport')
589
-			{
590
-				if (is_array($genallowed)) $modellist=$genallowed;
591
-				else
592
-				{
593
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
594
-					$modellist=ModeleExpenseReport::liste_modeles($this->db);
595
-				}
596
-			}
597
-			else if ($modulepart == 'unpaid')
598
-			{
599
-				$modellist='';
600
-			}
601
-			elseif ($modulepart == 'user')
602
-			{
603
-				if (is_array($genallowed)) $modellist=$genallowed;
604
-				else
605
-				{
606
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php';
607
-					$modellist=ModelePDFUser::liste_modeles($this->db);
608
-				}
609
-			}
610
-			elseif ($modulepart == 'usergroup')
611
-			{
612
-				if (is_array($genallowed)) $modellist=$genallowed;
613
-				else
614
-				{
615
-					include_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php';
616
-					$modellist=ModelePDFUserGroup::liste_modeles($this->db);
617
-				}
618
-			}
619
-			else
620
-			{
621
-				// For normalized standard modules
622
-				$file=dol_buildpath('/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
623
-				if (file_exists($file))
624
-				{
625
-					$res=include_once $file;
626
-				}
627
-				// For normalized external modules
628
-				else
629
-				{
630
-					$file=dol_buildpath('/'.$modulepart.'/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
631
-					$res=include_once $file;
632
-				}
633
-				$class='ModelePDF'.ucfirst($modulepart);
634
-				if (class_exists($class))
635
-				{
636
-					$modellist=call_user_func($class.'::liste_modeles',$this->db);
637
-				}
638
-				else
639
-				{
640
-					dol_print_error($this->db,'Bad value for modulepart');
641
-					return -1;
642
-				}
643
-			}
644
-
645
-			// Set headershown to avoid to have table opened a second time later
646
-			$headershown=1;
647
-
648
-			$buttonlabeltoshow=$buttonlabel;
649
-			if (empty($buttonlabel)) $buttonlabel=$langs->trans('Generate');
650
-
651
-			if ($conf->browser->layout == 'phone') $urlsource.='#'.$forname.'_form';   // So we switch to form after a generation
652
-			if (empty($noform)) $out.= '<form action="'.$urlsource.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc').'" id="'.$forname.'_form" method="post">';
653
-			$out.= '<input type="hidden" name="action" value="builddoc">';
654
-			$out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
655
-
656
-			$out.= load_fiche_titre($titletoshow, '', '');
657
-			$out.= '<div class="div-table-responsive-no-min">';
658
-			$out.= '<table class="liste formdoc noborder" summary="listofdocumentstable" width="100%">';
659
-
660
-			$out.= '<tr class="liste_titre">';
661
-
662
-			$addcolumforpicto=($delallowed || $printer || $morepicto);
663
-			$out.= '<th align="center" colspan="'.(3+($addcolumforpicto?1:0)).'" class="formdoc liste_titre maxwidthonsmartphone">';
664
-
665
-			// Model
666
-			if (! empty($modellist))
667
-			{
668
-				$out.= '<span class="hideonsmartphone">'.$langs->trans('Model').' </span>';
669
-				if (is_array($modellist) && count($modellist) == 1)    // If there is only one element
670
-				{
671
-					$arraykeys=array_keys($modellist);
672
-					$modelselected=$arraykeys[0];
673
-				}
674
-				$out.= $form->selectarray('model', $modellist, $modelselected, $showempty, 0, 0, '', 0, 0, 0, '', 'minwidth100');
675
-				if ($conf->use_javascript_ajax)
676
-				{
677
-					$out.= ajax_combobox('model');
678
-				}
679
-			}
680
-			else
681
-			{
682
-				$out.= '<div class="float">'.$langs->trans("Files").'</div>';
683
-			}
684
-
685
-			// Language code (if multilang)
686
-			if (($allowgenifempty || (is_array($modellist) && count($modellist) > 0)) && $conf->global->MAIN_MULTILANGS && ! $forcenomultilang && (! empty($modellist) || $showempty))
687
-			{
688
-				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
689
-				$formadmin=new FormAdmin($this->db);
690
-				$defaultlang=$codelang?$codelang:$langs->getDefaultLang();
691
-				$morecss='maxwidth150';
692
-				if ($conf->browser->layout == 'phone') $morecss='maxwidth100';
693
-				$out.= $formadmin->select_language($defaultlang, 'lang_id', 0, 0, 0, 0, 0, $morecss);
694
-			}
695
-			else
696
-			{
697
-				$out.= '&nbsp;';
698
-			}
699
-
700
-			// Button
701
-			$genbutton = '<input class="button buttongen" id="'.$forname.'_generatebutton" name="'.$forname.'_generatebutton"';
702
-			$genbutton.= ' type="submit" value="'.$buttonlabel.'"';
703
-			if (! $allowgenifempty && ! is_array($modellist) && empty($modellist)) $genbutton.= ' disabled';
704
-			$genbutton.= '>';
705
-			if ($allowgenifempty && ! is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid')
706
-			{
707
-			   	$langs->load("errors");
708
-			   	$genbutton.= ' '.img_warning($langs->transnoentitiesnoconv("WarningNoDocumentModelActivated"));
709
-			}
710
-			if (! $allowgenifempty && ! is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid') $genbutton='';
711
-			if (empty($modellist) && ! $showempty && $modulepart != 'unpaid') $genbutton='';
712
-			$out.= $genbutton;
713
-			$out.= '</th>';
714
-
715
-			if (!empty($hookmanager->hooks['formfile']))
716
-			{
717
-				foreach($hookmanager->hooks['formfile'] as $module)
718
-				{
719
-					if (method_exists($module, 'formBuilddocLineOptions')) $out .= '<th></th>';
720
-				}
721
-			}
722
-			$out.= '</tr>';
723
-
724
-			// Execute hooks
725
-			$parameters=array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''),'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''),'modulepart'=>$modulepart);
726
-			if (is_object($hookmanager))
727
-			{
728
-				$reshook = $hookmanager->executeHooks('formBuilddocOptions',$parameters,$GLOBALS['object']);
729
-				$out.= $hookmanager->resPrint;
730
-			}
731
-		}
732
-
733
-		// Get list of files
734
-		if (! empty($filedir))
735
-		{
736
-			$link_list = array();
737
-			if (is_object($object))
738
-			{
739
-				require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
740
-				$link = new Link($this->db);
741
-				$sortfield = $sortorder = null;
742
-				$res = $link->fetchAll($link_list, $object->element, $object->id, $sortfield, $sortorder);
743
-			}
744
-
745
-			$out.= '<!-- html.formfile::showdocuments -->'."\n";
746
-
747
-			// Show title of array if not already shown
748
-			if ((! empty($file_list) || ! empty($link_list) || preg_match('/^massfilesarea/', $modulepart))
749
-				&& ! $headershown)
750
-			{
751
-				$headershown=1;
752
-				$out.= '<div class="titre">'.$titletoshow.'</div>'."\n";
753
-				$out.= '<div class="div-table-responsive-no-min">';
754
-				$out.= '<table class="noborder" summary="listofdocumentstable" id="'.$modulepart.'_table" width="100%">'."\n";
755
-			}
756
-
757
-			// Loop on each file found
758
-			if (is_array($file_list))
759
-			{
760
-				foreach($file_list as $file)
761
-				{
762
-					// Define relative path for download link (depends on module)
763
-					$relativepath=$file["name"];										// Cas general
764
-					if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"];	// Cas propal, facture...
765
-					if ($modulepart == 'export') $relativepath = $file["name"];			// Other case
766
-
767
-					$out.= '<tr class="oddeven">';
768
-
769
-					$documenturl = DOL_URL_ROOT.'/document.php';
770
-					if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) $documenturl=$conf->global->DOL_URL_ROOT_DOCUMENT_PHP;    // To use another wrapper
771
-
772
-					// Show file name with link to download
773
-					$out.= '<td class="minwidth200">';
774
-					$out.= '<a class="documentdownload paddingright" href="'.$documenturl.'?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).($param?'&'.$param:'').'"';
775
-					$mime=dol_mimetype($relativepath,'',0);
776
-					if (preg_match('/text/',$mime)) $out.= ' target="_blank"';
777
-					$out.= ' target="_blank">';
778
-					$out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]);
779
-					$out.= dol_trunc($file["name"], 150);
780
-					$out.= '</a>'."\n";
781
-					$out.= $this->showPreview($file,$modulepart,$relativepath,0,$param);
782
-					$out.= '</td>';
783
-
784
-					// Show file size
785
-					$size=(! empty($file['size'])?$file['size']:dol_filesize($filedir."/".$file["name"]));
786
-					$out.= '<td align="right" class="nowrap">'.dol_print_size($size,1,1).'</td>';
787
-
788
-					// Show file date
789
-					$date=(! empty($file['date'])?$file['date']:dol_filemtime($filedir."/".$file["name"]));
790
-					$out.= '<td align="right" class="nowrap">'.dol_print_date($date, 'dayhour', 'tzuser').'</td>';
791
-
792
-					if ($delallowed || $printer || $morepicto)
793
-					{
794
-						$out.= '<td class="right nowraponall">';
795
-						if ($delallowed)
796
-						{
797
-							$tmpurlsource = preg_replace('/#[a-zA-Z0-9_]*$/', '', $urlsource);
798
-							$out.= '<a href="'.$tmpurlsource.(strpos($tmpurlsource,'?')?'&amp;':'?').'action=remove_file&amp;file='.urlencode($relativepath);
799
-							$out.= ($param?'&amp;'.$param:'');
800
-							//$out.= '&modulepart='.$modulepart; // TODO obsolete ?
801
-							//$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ?
802
-							$out.= '">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
803
-						}
804
-						if ($printer)
805
-						{
806
-							//$out.= '<td align="right">';
807
-							$out.= '<a class="paddingleft" href="'.$urlsource.(strpos($urlsource,'?')?'&amp;':'?').'action=print_file&amp;printer='.$modulepart.'&amp;file='.urlencode($relativepath);
808
-							$out.= ($param?'&amp;'.$param:'');
809
-							$out.= '">'.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').'</a>';
810
-						}
811
-						if ($morepicto)
812
-						{
813
-							$morepicto=preg_replace('/__FILENAMEURLENCODED__/',urlencode($relativepath),$morepicto);
814
-							$out.=$morepicto;
815
-						}
816
-						$out.='</td>';
817
-					}
818
-
819
-					if (is_object($hookmanager))
820
-					{
821
-						$parameters=array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''),'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''),'modulepart'=>$modulepart,'relativepath'=>$relativepath);
822
-						$res = $hookmanager->executeHooks('formBuilddocLineOptions',$parameters,$file);
823
-						if (empty($res))
824
-						{
825
-							$out.= $hookmanager->resPrint;		// Complete line
826
-							$out.= '</tr>';
827
-						}
828
-						else $out = $hookmanager->resPrint;		// Replace line
829
-			  		}
830
-				}
831
-
832
-				$this->numoffiles++;
833
-			}
834
-			// Loop on each link found
835
-			if (is_array($link_list))
836
-			{
837
-				$colspan=2;
838
-
839
-				foreach($link_list as $file)
840
-				{
841
-					$out.='<tr class="oddeven">';
842
-					$out.='<td colspan="'.$colspan.'" class="maxwidhtonsmartphone">';
843
-					$out.='<a data-ajax="false" href="' . $link->url . '" target="_blank">';
844
-					$out.=$file->label;
845
-					$out.='</a>';
846
-					$out.='</td>';
847
-					$out.='<td align="right">';
848
-					$out.=dol_print_date($file->datea,'dayhour');
849
-					$out.='</td>';
850
-					if ($delallowed || $printer || $morepicto) $out.='<td></td>';
851
-					$out.='</tr>'."\n";
852
-				}
853
-				$this->numoffiles++;
854
-			}
855
-
856
-		 	if (count($file_list) == 0 && count($link_list) == 0 && $headershown)
857
-			{
858
-				$out.='<tr><td colspan="'.(3+($addcolumforpicto?1:0)).'" class="opacitymedium">'.$langs->trans("None").'</td></tr>'."\n";
859
-			}
860
-		}
861
-
862
-		if ($headershown)
863
-		{
864
-			// Affiche pied du tableau
865
-			$out.= "</table>\n";
866
-			$out.= "</div>\n";
867
-			if ($genallowed)
868
-			{
869
-				if (empty($noform)) $out.= '</form>'."\n";
870
-			}
871
-		}
872
-		$out.= '<!-- End show_document -->'."\n";
873
-		//return ($i?$i:$headershown);
874
-		return $out;
875
-	}
876
-
877
-	/**
878
-	 *	Show a Document icon with link(s)
879
-	 *  You may want to call this into a div like this:
880
-	 *  print '<div class="inline-block valignmiddle">'.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'</div>';
881
-	 *
882
-	 *	@param	string	$modulepart		propal, facture, facture_fourn, ...
883
-	 *	@param	string	$modulesubdir	Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
884
-	 *	@param	string	$filedir		Full path to directory to scan
885
-	 *  @param	string	$filter			Filter filenames on this regex string (Example: '\.pdf$')
886
-	 *	@return	string              	Output string with HTML link of documents (might be empty string). This also fill the array ->infofiles
887
-	 */
888
-	function getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter='')
889
-	{
890
-		global $conf, $langs;
891
-
892
-		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
893
-
894
-		$out='';
895
-		$this->infofiles=array('nboffiles'=>0,'extensions'=>array(),'files'=>array());
896
-
897
-		$entity = 1; // Without multicompany
898
-
899
-		// Get object entity
900
-		if (! empty($conf->multicompany->enabled))
901
-		{
902
-			preg_match('/\/([0-9]+)\/[^\/]+\/'.preg_quote($modulesubdir,'/').'$/', $filedir, $regs);
903
-			$entity = ((! empty($regs[1]) && $regs[1] > 1) ? $regs[1] : 1); // If entity id not found in $filedir this is entity 1 by default
904
-		}
905
-
906
-		// Get list of files starting with name of ref (but not followed by "-" to discard uploaded files and get only generated files)
907
-		// @TODO Why not showing by default all files by just removing the '[^\-]+' at end of regex ?
908
-		if (! empty($conf->global->MAIN_SHOW_ALL_FILES_ON_DOCUMENT_TOOLTIP))
909
-		{
910
-			$filterforfilesearch = preg_quote(basename($modulesubdir),'/');
911
-		}
912
-		else
913
-		{
914
-			$filterforfilesearch = preg_quote(basename($modulesubdir),'/').'[^\-]+';
915
-		}
916
-		$file_list=dol_dir_list($filedir, 'files', 0, $filterforfilesearch, '\.meta$|\.png$');	// We also discard .meta and .png preview
917
-
918
-		//var_dump($file_list);
919
-		// For ajax treatment
920
-		$out.= '<!-- html.formfile::getDocumentsLink -->'."\n";
921
-		if (! empty($file_list))
922
-		{
923
-			$out='<dl class="dropdown inline-block">
422
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
423
+                    $modellist = ModelePdfReception::liste_modeles($this->db);
424
+                }
425
+            }
426
+            elseif ($modulepart == 'livraison')
427
+            {
428
+                if (is_array($genallowed)) $modellist=$genallowed;
429
+                else
430
+                {
431
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/livraison/modules_livraison.php';
432
+                    $modellist=ModelePDFDeliveryOrder::liste_modeles($this->db);
433
+                }
434
+            }
435
+            else if ($modulepart == 'ficheinter')
436
+            {
437
+                if (is_array($genallowed)) $modellist=$genallowed;
438
+                else
439
+                {
440
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/fichinter/modules_fichinter.php';
441
+                    $modellist=ModelePDFFicheinter::liste_modeles($this->db);
442
+                }
443
+            }
444
+            elseif ($modulepart == 'facture')
445
+            {
446
+                if (is_array($genallowed)) $modellist=$genallowed;
447
+                else
448
+                {
449
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
450
+                    $modellist=ModelePDFFactures::liste_modeles($this->db);
451
+                }
452
+            }
453
+            elseif ($modulepart == 'contract')
454
+            {
455
+                if (is_array($genallowed)) $modellist=$genallowed;
456
+                else
457
+                {
458
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php';
459
+                    $modellist=ModelePDFContract::liste_modeles($this->db);
460
+                }
461
+            }
462
+            elseif ($modulepart == 'project')
463
+            {
464
+                if (is_array($genallowed)) $modellist=$genallowed;
465
+                else
466
+                {
467
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
468
+                    $modellist=ModelePDFProjects::liste_modeles($this->db);
469
+                }
470
+            }
471
+            elseif ($modulepart == 'project_task')
472
+            {
473
+                if (is_array($genallowed)) $modellist=$genallowed;
474
+                else
475
+                {
476
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
477
+                    $modellist=ModelePDFTask::liste_modeles($this->db);
478
+                }
479
+            }
480
+            elseif ($modulepart == 'product')
481
+            {
482
+                if (is_array($genallowed)) $modellist=$genallowed;
483
+                else
484
+                {
485
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php';
486
+                    $modellist=ModelePDFProduct::liste_modeles($this->db);
487
+                }
488
+            }
489
+            elseif ($modulepart == 'product_batch')
490
+            {
491
+                if (is_array($genallowed)) $modellist=$genallowed;
492
+                else
493
+                {
494
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/product_batch/modules_product_batch.class.php';
495
+                    $modellist=ModelePDFProductBatch::liste_modeles($this->db);
496
+                }
497
+            }
498
+            elseif ($modulepart == 'stock')
499
+            {
500
+                if (is_array($genallowed)) $modellist=$genallowed;
501
+                else
502
+                {
503
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_stock.php';
504
+                    $modellist=ModelePDFStock::liste_modeles($this->db);
505
+                }
506
+            }
507
+            elseif ($modulepart == 'movement')
508
+            {
509
+                if (is_array($genallowed)) $modellist=$genallowed;
510
+                else
511
+                {
512
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/stock/modules_movement.php';
513
+                    $modellist=ModelePDFMovement::liste_modeles($this->db);
514
+                }
515
+            }
516
+            elseif ($modulepart == 'export')
517
+            {
518
+                if (is_array($genallowed)) $modellist=$genallowed;
519
+                else
520
+                {
521
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php';
522
+                    $modellist=ModeleExports::liste_modeles($this->db);
523
+                }
524
+            }
525
+            else if ($modulepart == 'commande_fournisseur' || $modulepart == 'supplier_order')
526
+            {
527
+                if (is_array($genallowed)) $modellist=$genallowed;
528
+                else
529
+                {
530
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
531
+                    $modellist=ModelePDFSuppliersOrders::liste_modeles($this->db);
532
+                }
533
+            }
534
+            else if ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice')
535
+            {
536
+                if (is_array($genallowed)) $modellist=$genallowed;
537
+                else
538
+                {
539
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
540
+                    $modellist=ModelePDFSuppliersInvoices::liste_modeles($this->db);
541
+                }
542
+            }
543
+            else if ($modulepart == 'supplier_payment')
544
+            {
545
+                if (is_array($genallowed)) $modellist=$genallowed;
546
+                else
547
+                {
548
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_payment/modules_supplier_payment.php';
549
+                    $modellist=ModelePDFSuppliersPayments::liste_modeles($this->db);
550
+                }
551
+            }
552
+            else if ($modulepart == 'remisecheque')
553
+            {
554
+                if (is_array($genallowed)) $modellist=$genallowed;
555
+                else
556
+                {
557
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/cheque/modules_chequereceipts.php';
558
+                    $modellist=ModeleChequeReceipts::liste_modeles($this->db);
559
+                }
560
+            }
561
+            elseif ($modulepart == 'donation')
562
+            {
563
+                if (is_array($genallowed)) $modellist=$genallowed;
564
+                else
565
+                {
566
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/dons/modules_don.php';
567
+                    $modellist=ModeleDon::liste_modeles($this->db);
568
+                }
569
+            }
570
+            elseif ($modulepart == 'member')
571
+            {
572
+                if (is_array($genallowed)) $modellist=$genallowed;
573
+                else
574
+                {
575
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/member/modules_cards.php';
576
+                    $modellist=ModelePDFCards::liste_modeles($this->db);
577
+                }
578
+            }
579
+            elseif ($modulepart == 'agenda' || $modulepart == 'actions')
580
+            {
581
+                if (is_array($genallowed)) $modellist=$genallowed;
582
+                else
583
+                {
584
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/action/modules_action.php';
585
+                    $modellist=ModeleAction::liste_modeles($this->db);
586
+                }
587
+            }
588
+            else if ($modulepart == 'expensereport')
589
+            {
590
+                if (is_array($genallowed)) $modellist=$genallowed;
591
+                else
592
+                {
593
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
594
+                    $modellist=ModeleExpenseReport::liste_modeles($this->db);
595
+                }
596
+            }
597
+            else if ($modulepart == 'unpaid')
598
+            {
599
+                $modellist='';
600
+            }
601
+            elseif ($modulepart == 'user')
602
+            {
603
+                if (is_array($genallowed)) $modellist=$genallowed;
604
+                else
605
+                {
606
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/user/modules_user.class.php';
607
+                    $modellist=ModelePDFUser::liste_modeles($this->db);
608
+                }
609
+            }
610
+            elseif ($modulepart == 'usergroup')
611
+            {
612
+                if (is_array($genallowed)) $modellist=$genallowed;
613
+                else
614
+                {
615
+                    include_once DOL_DOCUMENT_ROOT.'/core/modules/usergroup/modules_usergroup.class.php';
616
+                    $modellist=ModelePDFUserGroup::liste_modeles($this->db);
617
+                }
618
+            }
619
+            else
620
+            {
621
+                // For normalized standard modules
622
+                $file=dol_buildpath('/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
623
+                if (file_exists($file))
624
+                {
625
+                    $res=include_once $file;
626
+                }
627
+                // For normalized external modules
628
+                else
629
+                {
630
+                    $file=dol_buildpath('/'.$modulepart.'/core/modules/'.$modulepart.'/modules_'.$modulepart.'.php',0);
631
+                    $res=include_once $file;
632
+                }
633
+                $class='ModelePDF'.ucfirst($modulepart);
634
+                if (class_exists($class))
635
+                {
636
+                    $modellist=call_user_func($class.'::liste_modeles',$this->db);
637
+                }
638
+                else
639
+                {
640
+                    dol_print_error($this->db,'Bad value for modulepart');
641
+                    return -1;
642
+                }
643
+            }
644
+
645
+            // Set headershown to avoid to have table opened a second time later
646
+            $headershown=1;
647
+
648
+            $buttonlabeltoshow=$buttonlabel;
649
+            if (empty($buttonlabel)) $buttonlabel=$langs->trans('Generate');
650
+
651
+            if ($conf->browser->layout == 'phone') $urlsource.='#'.$forname.'_form';   // So we switch to form after a generation
652
+            if (empty($noform)) $out.= '<form action="'.$urlsource.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc').'" id="'.$forname.'_form" method="post">';
653
+            $out.= '<input type="hidden" name="action" value="builddoc">';
654
+            $out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
655
+
656
+            $out.= load_fiche_titre($titletoshow, '', '');
657
+            $out.= '<div class="div-table-responsive-no-min">';
658
+            $out.= '<table class="liste formdoc noborder" summary="listofdocumentstable" width="100%">';
659
+
660
+            $out.= '<tr class="liste_titre">';
661
+
662
+            $addcolumforpicto=($delallowed || $printer || $morepicto);
663
+            $out.= '<th align="center" colspan="'.(3+($addcolumforpicto?1:0)).'" class="formdoc liste_titre maxwidthonsmartphone">';
664
+
665
+            // Model
666
+            if (! empty($modellist))
667
+            {
668
+                $out.= '<span class="hideonsmartphone">'.$langs->trans('Model').' </span>';
669
+                if (is_array($modellist) && count($modellist) == 1)    // If there is only one element
670
+                {
671
+                    $arraykeys=array_keys($modellist);
672
+                    $modelselected=$arraykeys[0];
673
+                }
674
+                $out.= $form->selectarray('model', $modellist, $modelselected, $showempty, 0, 0, '', 0, 0, 0, '', 'minwidth100');
675
+                if ($conf->use_javascript_ajax)
676
+                {
677
+                    $out.= ajax_combobox('model');
678
+                }
679
+            }
680
+            else
681
+            {
682
+                $out.= '<div class="float">'.$langs->trans("Files").'</div>';
683
+            }
684
+
685
+            // Language code (if multilang)
686
+            if (($allowgenifempty || (is_array($modellist) && count($modellist) > 0)) && $conf->global->MAIN_MULTILANGS && ! $forcenomultilang && (! empty($modellist) || $showempty))
687
+            {
688
+                include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
689
+                $formadmin=new FormAdmin($this->db);
690
+                $defaultlang=$codelang?$codelang:$langs->getDefaultLang();
691
+                $morecss='maxwidth150';
692
+                if ($conf->browser->layout == 'phone') $morecss='maxwidth100';
693
+                $out.= $formadmin->select_language($defaultlang, 'lang_id', 0, 0, 0, 0, 0, $morecss);
694
+            }
695
+            else
696
+            {
697
+                $out.= '&nbsp;';
698
+            }
699
+
700
+            // Button
701
+            $genbutton = '<input class="button buttongen" id="'.$forname.'_generatebutton" name="'.$forname.'_generatebutton"';
702
+            $genbutton.= ' type="submit" value="'.$buttonlabel.'"';
703
+            if (! $allowgenifempty && ! is_array($modellist) && empty($modellist)) $genbutton.= ' disabled';
704
+            $genbutton.= '>';
705
+            if ($allowgenifempty && ! is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid')
706
+            {
707
+                    $langs->load("errors");
708
+                    $genbutton.= ' '.img_warning($langs->transnoentitiesnoconv("WarningNoDocumentModelActivated"));
709
+            }
710
+            if (! $allowgenifempty && ! is_array($modellist) && empty($modellist) && empty($conf->dol_no_mouse_hover) && $modulepart != 'unpaid') $genbutton='';
711
+            if (empty($modellist) && ! $showempty && $modulepart != 'unpaid') $genbutton='';
712
+            $out.= $genbutton;
713
+            $out.= '</th>';
714
+
715
+            if (!empty($hookmanager->hooks['formfile']))
716
+            {
717
+                foreach($hookmanager->hooks['formfile'] as $module)
718
+                {
719
+                    if (method_exists($module, 'formBuilddocLineOptions')) $out .= '<th></th>';
720
+                }
721
+            }
722
+            $out.= '</tr>';
723
+
724
+            // Execute hooks
725
+            $parameters=array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''),'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''),'modulepart'=>$modulepart);
726
+            if (is_object($hookmanager))
727
+            {
728
+                $reshook = $hookmanager->executeHooks('formBuilddocOptions',$parameters,$GLOBALS['object']);
729
+                $out.= $hookmanager->resPrint;
730
+            }
731
+        }
732
+
733
+        // Get list of files
734
+        if (! empty($filedir))
735
+        {
736
+            $link_list = array();
737
+            if (is_object($object))
738
+            {
739
+                require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
740
+                $link = new Link($this->db);
741
+                $sortfield = $sortorder = null;
742
+                $res = $link->fetchAll($link_list, $object->element, $object->id, $sortfield, $sortorder);
743
+            }
744
+
745
+            $out.= '<!-- html.formfile::showdocuments -->'."\n";
746
+
747
+            // Show title of array if not already shown
748
+            if ((! empty($file_list) || ! empty($link_list) || preg_match('/^massfilesarea/', $modulepart))
749
+                && ! $headershown)
750
+            {
751
+                $headershown=1;
752
+                $out.= '<div class="titre">'.$titletoshow.'</div>'."\n";
753
+                $out.= '<div class="div-table-responsive-no-min">';
754
+                $out.= '<table class="noborder" summary="listofdocumentstable" id="'.$modulepart.'_table" width="100%">'."\n";
755
+            }
756
+
757
+            // Loop on each file found
758
+            if (is_array($file_list))
759
+            {
760
+                foreach($file_list as $file)
761
+                {
762
+                    // Define relative path for download link (depends on module)
763
+                    $relativepath=$file["name"];										// Cas general
764
+                    if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"];	// Cas propal, facture...
765
+                    if ($modulepart == 'export') $relativepath = $file["name"];			// Other case
766
+
767
+                    $out.= '<tr class="oddeven">';
768
+
769
+                    $documenturl = DOL_URL_ROOT.'/document.php';
770
+                    if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) $documenturl=$conf->global->DOL_URL_ROOT_DOCUMENT_PHP;    // To use another wrapper
771
+
772
+                    // Show file name with link to download
773
+                    $out.= '<td class="minwidth200">';
774
+                    $out.= '<a class="documentdownload paddingright" href="'.$documenturl.'?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).($param?'&'.$param:'').'"';
775
+                    $mime=dol_mimetype($relativepath,'',0);
776
+                    if (preg_match('/text/',$mime)) $out.= ' target="_blank"';
777
+                    $out.= ' target="_blank">';
778
+                    $out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]);
779
+                    $out.= dol_trunc($file["name"], 150);
780
+                    $out.= '</a>'."\n";
781
+                    $out.= $this->showPreview($file,$modulepart,$relativepath,0,$param);
782
+                    $out.= '</td>';
783
+
784
+                    // Show file size
785
+                    $size=(! empty($file['size'])?$file['size']:dol_filesize($filedir."/".$file["name"]));
786
+                    $out.= '<td align="right" class="nowrap">'.dol_print_size($size,1,1).'</td>';
787
+
788
+                    // Show file date
789
+                    $date=(! empty($file['date'])?$file['date']:dol_filemtime($filedir."/".$file["name"]));
790
+                    $out.= '<td align="right" class="nowrap">'.dol_print_date($date, 'dayhour', 'tzuser').'</td>';
791
+
792
+                    if ($delallowed || $printer || $morepicto)
793
+                    {
794
+                        $out.= '<td class="right nowraponall">';
795
+                        if ($delallowed)
796
+                        {
797
+                            $tmpurlsource = preg_replace('/#[a-zA-Z0-9_]*$/', '', $urlsource);
798
+                            $out.= '<a href="'.$tmpurlsource.(strpos($tmpurlsource,'?')?'&amp;':'?').'action=remove_file&amp;file='.urlencode($relativepath);
799
+                            $out.= ($param?'&amp;'.$param:'');
800
+                            //$out.= '&modulepart='.$modulepart; // TODO obsolete ?
801
+                            //$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ?
802
+                            $out.= '">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
803
+                        }
804
+                        if ($printer)
805
+                        {
806
+                            //$out.= '<td align="right">';
807
+                            $out.= '<a class="paddingleft" href="'.$urlsource.(strpos($urlsource,'?')?'&amp;':'?').'action=print_file&amp;printer='.$modulepart.'&amp;file='.urlencode($relativepath);
808
+                            $out.= ($param?'&amp;'.$param:'');
809
+                            $out.= '">'.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').'</a>';
810
+                        }
811
+                        if ($morepicto)
812
+                        {
813
+                            $morepicto=preg_replace('/__FILENAMEURLENCODED__/',urlencode($relativepath),$morepicto);
814
+                            $out.=$morepicto;
815
+                        }
816
+                        $out.='</td>';
817
+                    }
818
+
819
+                    if (is_object($hookmanager))
820
+                    {
821
+                        $parameters=array('socid'=>(isset($GLOBALS['socid'])?$GLOBALS['socid']:''),'id'=>(isset($GLOBALS['id'])?$GLOBALS['id']:''),'modulepart'=>$modulepart,'relativepath'=>$relativepath);
822
+                        $res = $hookmanager->executeHooks('formBuilddocLineOptions',$parameters,$file);
823
+                        if (empty($res))
824
+                        {
825
+                            $out.= $hookmanager->resPrint;		// Complete line
826
+                            $out.= '</tr>';
827
+                        }
828
+                        else $out = $hookmanager->resPrint;		// Replace line
829
+                        }
830
+                }
831
+
832
+                $this->numoffiles++;
833
+            }
834
+            // Loop on each link found
835
+            if (is_array($link_list))
836
+            {
837
+                $colspan=2;
838
+
839
+                foreach($link_list as $file)
840
+                {
841
+                    $out.='<tr class="oddeven">';
842
+                    $out.='<td colspan="'.$colspan.'" class="maxwidhtonsmartphone">';
843
+                    $out.='<a data-ajax="false" href="' . $link->url . '" target="_blank">';
844
+                    $out.=$file->label;
845
+                    $out.='</a>';
846
+                    $out.='</td>';
847
+                    $out.='<td align="right">';
848
+                    $out.=dol_print_date($file->datea,'dayhour');
849
+                    $out.='</td>';
850
+                    if ($delallowed || $printer || $morepicto) $out.='<td></td>';
851
+                    $out.='</tr>'."\n";
852
+                }
853
+                $this->numoffiles++;
854
+            }
855
+
856
+                if (count($file_list) == 0 && count($link_list) == 0 && $headershown)
857
+            {
858
+                $out.='<tr><td colspan="'.(3+($addcolumforpicto?1:0)).'" class="opacitymedium">'.$langs->trans("None").'</td></tr>'."\n";
859
+            }
860
+        }
861
+
862
+        if ($headershown)
863
+        {
864
+            // Affiche pied du tableau
865
+            $out.= "</table>\n";
866
+            $out.= "</div>\n";
867
+            if ($genallowed)
868
+            {
869
+                if (empty($noform)) $out.= '</form>'."\n";
870
+            }
871
+        }
872
+        $out.= '<!-- End show_document -->'."\n";
873
+        //return ($i?$i:$headershown);
874
+        return $out;
875
+    }
876
+
877
+    /**
878
+     *	Show a Document icon with link(s)
879
+     *  You may want to call this into a div like this:
880
+     *  print '<div class="inline-block valignmiddle">'.$formfile->getDocumentsLink($element_doc, $filename, $filedir).'</div>';
881
+     *
882
+     *	@param	string	$modulepart		propal, facture, facture_fourn, ...
883
+     *	@param	string	$modulesubdir	Sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module.
884
+     *	@param	string	$filedir		Full path to directory to scan
885
+     *  @param	string	$filter			Filter filenames on this regex string (Example: '\.pdf$')
886
+     *	@return	string              	Output string with HTML link of documents (might be empty string). This also fill the array ->infofiles
887
+     */
888
+    function getDocumentsLink($modulepart, $modulesubdir, $filedir, $filter='')
889
+    {
890
+        global $conf, $langs;
891
+
892
+        include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
893
+
894
+        $out='';
895
+        $this->infofiles=array('nboffiles'=>0,'extensions'=>array(),'files'=>array());
896
+
897
+        $entity = 1; // Without multicompany
898
+
899
+        // Get object entity
900
+        if (! empty($conf->multicompany->enabled))
901
+        {
902
+            preg_match('/\/([0-9]+)\/[^\/]+\/'.preg_quote($modulesubdir,'/').'$/', $filedir, $regs);
903
+            $entity = ((! empty($regs[1]) && $regs[1] > 1) ? $regs[1] : 1); // If entity id not found in $filedir this is entity 1 by default
904
+        }
905
+
906
+        // Get list of files starting with name of ref (but not followed by "-" to discard uploaded files and get only generated files)
907
+        // @TODO Why not showing by default all files by just removing the '[^\-]+' at end of regex ?
908
+        if (! empty($conf->global->MAIN_SHOW_ALL_FILES_ON_DOCUMENT_TOOLTIP))
909
+        {
910
+            $filterforfilesearch = preg_quote(basename($modulesubdir),'/');
911
+        }
912
+        else
913
+        {
914
+            $filterforfilesearch = preg_quote(basename($modulesubdir),'/').'[^\-]+';
915
+        }
916
+        $file_list=dol_dir_list($filedir, 'files', 0, $filterforfilesearch, '\.meta$|\.png$');	// We also discard .meta and .png preview
917
+
918
+        //var_dump($file_list);
919
+        // For ajax treatment
920
+        $out.= '<!-- html.formfile::getDocumentsLink -->'."\n";
921
+        if (! empty($file_list))
922
+        {
923
+            $out='<dl class="dropdown inline-block">
924 924
     			<dt><a data-ajax="false" href="#" onClick="return false;">'.img_picto('', 'listlight', '', 0, 0, 0, '', 'valignmiddle').'</a></dt>
925 925
     			<dd><div class="multichoicedoc" style="position:absolute;left:100px;" ><ul class="ulselectedfields" style="display: none;">';
926
-			$tmpout='';
927
-
928
-			// Loop on each file found
929
-			$found=0;
930
-			foreach($file_list as $file)
931
-			{
932
-				$i++;
933
-				if ($filter && ! preg_match('/'.$filter.'/i', $file["name"])) continue;	// Discard this. It does not match provided filter.
934
-
935
-				$found++;
936
-				// Define relative path for download link (depends on module)
937
-				$relativepath=$file["name"];								// Cas general
938
-				if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"];	// Cas propal, facture...
939
-				// Autre cas
940
-				if ($modulepart == 'donation')            {
941
-					$relativepath = get_exdir($modulesubdir,2,0,0,null,'donation').$file["name"];
942
-				}
943
-				if ($modulepart == 'export')              {
944
-					$relativepath = $file["name"];
945
-				}
946
-
947
-				$this->infofiles['nboffiles']++;
948
-				$this->infofiles['files'][]=$file['fullname'];
949
-				$ext=pathinfo($file["name"], PATHINFO_EXTENSION);
950
-				if (empty($this->infofiles[$ext])) $this->infofiles['extensions'][$ext]=1;
951
-				else $this->infofiles['extensions'][$ext]++;
952
-
953
-				// Preview
954
-				if (! empty($conf->use_javascript_ajax) && ($conf->browser->layout != 'phone'))
955
-				{
956
-					$tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1, '&entity='.$entity);
957
-					if ($tmparray && $tmparray['url'])
958
-					{
959
-						$tmpout.= '<li><a href="'.$tmparray['url'].'"'.($tmparray['css']?' class="'.$tmparray['css'].'"':'').($tmparray['mime']?' mime="'.$tmparray['mime'].'"':'').($tmparray['target']?' target="'.$tmparray['target'].'"':'').'>';
960
-						//$tmpout.= img_picto('','detail');
961
-						$tmpout.= '<i class="fa fa-search-plus paddingright" style="color: gray"></i>';
962
-						$tmpout.= $langs->trans("Preview").' '.$ext.'</a></li>';
963
-					}
964
-				}
965
-
966
-				// Download
967
-				$tmpout.= '<li class="nowrap"><a class="pictopreview nowrap" href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;entity='.$entity.'&amp;file='.urlencode($relativepath).'"';
968
-				$mime=dol_mimetype($relativepath,'',0);
969
-				if (preg_match('/text/',$mime)) $tmpout.= ' target="_blank"';
970
-				$tmpout.= '>';
971
-				$tmpout.= img_mime($relativepath, $file["name"]);
972
-				$tmpout.= $langs->trans("Download").' '.$ext;
973
-				$tmpout.= '</a></li>'."\n";
974
-			}
975
-			$out.=$tmpout;
976
-			$out.='</ul></div></dd>
926
+            $tmpout='';
927
+
928
+            // Loop on each file found
929
+            $found=0;
930
+            foreach($file_list as $file)
931
+            {
932
+                $i++;
933
+                if ($filter && ! preg_match('/'.$filter.'/i', $file["name"])) continue;	// Discard this. It does not match provided filter.
934
+
935
+                $found++;
936
+                // Define relative path for download link (depends on module)
937
+                $relativepath=$file["name"];								// Cas general
938
+                if ($modulesubdir) $relativepath=$modulesubdir."/".$file["name"];	// Cas propal, facture...
939
+                // Autre cas
940
+                if ($modulepart == 'donation')            {
941
+                    $relativepath = get_exdir($modulesubdir,2,0,0,null,'donation').$file["name"];
942
+                }
943
+                if ($modulepart == 'export')              {
944
+                    $relativepath = $file["name"];
945
+                }
946
+
947
+                $this->infofiles['nboffiles']++;
948
+                $this->infofiles['files'][]=$file['fullname'];
949
+                $ext=pathinfo($file["name"], PATHINFO_EXTENSION);
950
+                if (empty($this->infofiles[$ext])) $this->infofiles['extensions'][$ext]=1;
951
+                else $this->infofiles['extensions'][$ext]++;
952
+
953
+                // Preview
954
+                if (! empty($conf->use_javascript_ajax) && ($conf->browser->layout != 'phone'))
955
+                {
956
+                    $tmparray = getAdvancedPreviewUrl($modulepart, $relativepath, 1, '&entity='.$entity);
957
+                    if ($tmparray && $tmparray['url'])
958
+                    {
959
+                        $tmpout.= '<li><a href="'.$tmparray['url'].'"'.($tmparray['css']?' class="'.$tmparray['css'].'"':'').($tmparray['mime']?' mime="'.$tmparray['mime'].'"':'').($tmparray['target']?' target="'.$tmparray['target'].'"':'').'>';
960
+                        //$tmpout.= img_picto('','detail');
961
+                        $tmpout.= '<i class="fa fa-search-plus paddingright" style="color: gray"></i>';
962
+                        $tmpout.= $langs->trans("Preview").' '.$ext.'</a></li>';
963
+                    }
964
+                }
965
+
966
+                // Download
967
+                $tmpout.= '<li class="nowrap"><a class="pictopreview nowrap" href="'.DOL_URL_ROOT . '/document.php?modulepart='.$modulepart.'&amp;entity='.$entity.'&amp;file='.urlencode($relativepath).'"';
968
+                $mime=dol_mimetype($relativepath,'',0);
969
+                if (preg_match('/text/',$mime)) $tmpout.= ' target="_blank"';
970
+                $tmpout.= '>';
971
+                $tmpout.= img_mime($relativepath, $file["name"]);
972
+                $tmpout.= $langs->trans("Download").' '.$ext;
973
+                $tmpout.= '</a></li>'."\n";
974
+            }
975
+            $out.=$tmpout;
976
+            $out.='</ul></div></dd>
977 977
     			</dl>';
978 978
 
979
-			if (! $found) $out='';
980
-		}
981
-		else
982
-		{
983
-			// TODO Add link to regenerate doc ?
984
-			//$out.= '<div id="gen_pdf_'.$modulesubdir.'" class="linkobject hideobject">'.img_picto('', 'refresh').'</div>'."\n";
985
-		}
979
+            if (! $found) $out='';
980
+        }
981
+        else
982
+        {
983
+            // TODO Add link to regenerate doc ?
984
+            //$out.= '<div id="gen_pdf_'.$modulesubdir.'" class="linkobject hideobject">'.img_picto('', 'refresh').'</div>'."\n";
985
+        }
986 986
 
987
-		return $out;
988
-	}
987
+        return $out;
988
+    }
989 989
 
990 990
 
991 991
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
992
-	/**
993
-	 *  Show list of documents in $filearray (may be they are all in same directory but may not)
994
-	 *  This also sync database if $upload_dir is defined.
995
-	 *
996
-	 *  @param	 array	$filearray          Array of files loaded by dol_dir_list('files') function before calling this.
997
-	 * 	@param	 Object	$object				Object on which document is linked to.
998
-	 * 	@param	 string	$modulepart			Value for modulepart used by download or viewimage wrapper.
999
-	 * 	@param	 string	$param				Parameters on sort links (param must start with &, example &aaa=bbb&ccc=ddd)
1000
-	 * 	@param	 int	$forcedownload		Force to open dialog box "Save As" when clicking on file.
1001
-	 * 	@param	 string	$relativepath		Relative path of docs (autodefined if not provided), relative to module dir, not to MAIN_DATA_ROOT.
1002
-	 * 	@param	 int	$permonobject		Permission on object (so permission to delete or crop document)
1003
-	 * 	@param	 int	$useinecm			Change output for use in ecm module:
1004
-	 * 										0: Add a previw link. Show also rename and crop file
1005
-	 * 										1: Add link to edit ECM entry
1006
-	 * 										2: Add rename and crop file
1007
-	 * 	@param	 string	$textifempty		Text to show if filearray is empty ('NoFileFound' if not defined)
1008
-	 *  @param   int	$maxlength          Maximum length of file name shown.
1009
-	 *  @param	 string	$title				Title before list. Use 'none' to disable title.
1010
-	 *  @param	 string $url				Full url to use for click links ('' = autodetect)
1011
-	 *  @param	 int	$showrelpart		0=Show only filename (default), 1=Show first level 1 dir
1012
-	 *  @param   int    $permtoeditline     Permission to edit document line (You must provide a value, -1 is deprecated and must not be used any more)
1013
-	 *  @param   string $upload_dir         Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this to complete file data with database indexes.
1014
-	 *  @param   string $sortfield          Sort field ('name', 'size', 'position', ...)
1015
-	 *  @param   string $sortorder          Sort order ('ASC' or 'DESC')
1016
-	 *  @param   int    $disablemove        1=Disable move button, 0=Position move is possible.
1017
-	 *  @param	 int	$addfilterfields	Add line with filters
1018
-	 * 	@return	 int						<0 if KO, nb of files shown if OK
1019
-	 *  @see list_of_autoecmfiles
1020
-	 */
1021
-	function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='',$sortfield='',$sortorder='ASC', $disablemove=1, $addfilterfields=0)
1022
-	{
992
+    /**
993
+     *  Show list of documents in $filearray (may be they are all in same directory but may not)
994
+     *  This also sync database if $upload_dir is defined.
995
+     *
996
+     *  @param	 array	$filearray          Array of files loaded by dol_dir_list('files') function before calling this.
997
+     * 	@param	 Object	$object				Object on which document is linked to.
998
+     * 	@param	 string	$modulepart			Value for modulepart used by download or viewimage wrapper.
999
+     * 	@param	 string	$param				Parameters on sort links (param must start with &, example &aaa=bbb&ccc=ddd)
1000
+     * 	@param	 int	$forcedownload		Force to open dialog box "Save As" when clicking on file.
1001
+     * 	@param	 string	$relativepath		Relative path of docs (autodefined if not provided), relative to module dir, not to MAIN_DATA_ROOT.
1002
+     * 	@param	 int	$permonobject		Permission on object (so permission to delete or crop document)
1003
+     * 	@param	 int	$useinecm			Change output for use in ecm module:
1004
+     * 										0: Add a previw link. Show also rename and crop file
1005
+     * 										1: Add link to edit ECM entry
1006
+     * 										2: Add rename and crop file
1007
+     * 	@param	 string	$textifempty		Text to show if filearray is empty ('NoFileFound' if not defined)
1008
+     *  @param   int	$maxlength          Maximum length of file name shown.
1009
+     *  @param	 string	$title				Title before list. Use 'none' to disable title.
1010
+     *  @param	 string $url				Full url to use for click links ('' = autodetect)
1011
+     *  @param	 int	$showrelpart		0=Show only filename (default), 1=Show first level 1 dir
1012
+     *  @param   int    $permtoeditline     Permission to edit document line (You must provide a value, -1 is deprecated and must not be used any more)
1013
+     *  @param   string $upload_dir         Full path directory so we can know dir relative to MAIN_DATA_ROOT. Fill this to complete file data with database indexes.
1014
+     *  @param   string $sortfield          Sort field ('name', 'size', 'position', ...)
1015
+     *  @param   string $sortorder          Sort order ('ASC' or 'DESC')
1016
+     *  @param   int    $disablemove        1=Disable move button, 0=Position move is possible.
1017
+     *  @param	 int	$addfilterfields	Add line with filters
1018
+     * 	@return	 int						<0 if KO, nb of files shown if OK
1019
+     *  @see list_of_autoecmfiles
1020
+     */
1021
+    function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='',$sortfield='',$sortorder='ASC', $disablemove=1, $addfilterfields=0)
1022
+    {
1023 1023
         // phpcs:enable
1024
-		global $user, $conf, $langs, $hookmanager;
1025
-		global $sortfield, $sortorder, $maxheightmini;
1026
-		global $dolibarr_main_url_root;
1027
-		global $form;
1028
-
1029
-		$disablecrop=1;
1030
-		if (in_array($modulepart, array('expensereport','holiday','member','project','product','produit','service','societe','tax','ticket','user'))) $disablecrop=0;
1031
-
1032
-		// Define relative path used to store the file
1033
-		if (empty($relativepath))
1034
-		{
1035
-			$relativepath=(! empty($object->ref)?dol_sanitizeFileName($object->ref):'').'/';
1036
-			if ($object->element == 'invoice_supplier') $relativepath=get_exdir($object->id,2,0,0,$object,'invoice_supplier').$relativepath;	// TODO Call using a defined value for $relativepath
1037
-			if ($object->element == 'project_task') $relativepath='Call_not_supported_._Call_function_using_a_defined_relative_path_.';
1038
-		}
1039
-		// For backward compatiblity, we detect file stored into an old path
1040
-		if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $filearray[0]['level1name'] == 'photos')
1041
-		{
1042
-		    $relativepath=preg_replace('/^.*\/produit\//','',$filearray[0]['path']).'/';
1043
-		}
1044
-		// Defined relative dir to DOL_DATA_ROOT
1045
-		$relativedir = '';
1046
-		if ($upload_dir)
1047
-		{
1048
-			$relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir);
1049
-			$relativedir = preg_replace('/^[\\/]/','',$relativedir);
1050
-		}
1051
-
1052
-		$hookmanager->initHooks(array('formfile'));
1053
-		$parameters=array(
1054
-				'filearray' => $filearray,
1055
-				'modulepart'=> $modulepart,
1056
-				'param' => $param,
1057
-				'forcedownload' => $forcedownload,
1058
-				'relativepath' => $relativepath,    // relative filename to module dir
1059
-				'relativedir' => $relativedir,      // relative dirname to DOL_DATA_ROOT
1060
-				'permtodelete' => $permonobject,
1061
-				'useinecm' => $useinecm,
1062
-				'textifempty' => $textifempty,
1063
-				'maxlength' => $maxlength,
1064
-				'title' => $title,
1065
-				'url' => $url
1066
-		);
1067
-		$reshook=$hookmanager->executeHooks('showFilesList', $parameters, $object);
1068
-
1069
-		if (isset($reshook) && $reshook != '') // null or '' for bypass
1070
-		{
1071
-			return $reshook;
1072
-		}
1073
-		else
1074
-		{
1075
-			if (! is_object($form))
1076
-			{
1077
-				include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';		// The compoent may be included into ajax page that does not include the Form class
1078
-				$form=new Form($this->db);
1079
-			}
1080
-
1081
-			if (! preg_match('/&id=/', $param) && isset($object->id)) $param.='&id='.$object->id;
1082
-			$relativepathwihtoutslashend=preg_replace('/\/$/', '', $relativepath);
1083
-			if ($relativepathwihtoutslashend) $param.= '&file='.urlencode($relativepathwihtoutslashend);
1084
-
1085
-			if ($permtoeditline < 0)  // Old behaviour for backward compatibility. New feature should call method with value 0 or 1
1086
-			{
1087
-				$permtoeditline=0;
1088
-				if (in_array($modulepart, array('product','produit','service')))
1089
-				{
1090
-					if ($user->rights->produit->creer && $object->type == Product::TYPE_PRODUCT) $permtoeditline=1;
1091
-					if ($user->rights->service->creer && $object->type == Product::TYPE_SERVICE) $permtoeditline=1;
1092
-				}
1093
-			}
1094
-			if (empty($conf->global->MAIN_UPLOAD_DOC))
1095
-			{
1096
-				$permtoeditline=0;
1097
-				$permonobject=0;
1098
-			}
1099
-
1100
-			// Show list of existing files
1101
-			if (empty($useinecm) && $title != 'none') print load_fiche_titre($title?$title:$langs->trans("AttachedFiles"));
1102
-			if (empty($url)) $url=$_SERVER["PHP_SELF"];
1103
-
1104
-			print '<!-- html.formfile::list_of_documents -->'."\n";
1105
-			if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline)
1106
-			{
1107
-				print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param.'" method="POST">';
1108
-				print '<input type="hidden" name="action" value="renamefile">';
1109
-				print '<input type="hidden" name="id" value="'.$object->id.'">';
1110
-				print '<input type="hidden" name="modulepart" value="'.$modulepart.'">';
1111
-			}
1112
-
1113
-			print '<div class="div-table-responsive-no-min">';
1114
-			print '<table width="100%" id="tablelines" class="'.($useinecm?'liste noborder':'liste').'">'."\n";
1115
-
1116
-			if (! empty($addfilterfields))
1117
-			{
1118
-				print '<tr class="liste_titre nodrag nodrop">';
1119
-				print '<td><input type="search_doc_ref" value="'.dol_escape_htmltag(GETPOST('search_doc_ref','alpha')).'"></td>';
1120
-				print '<td></td>';
1121
-				print '<td></td>';
1122
-				if (empty($useinecm)) print '<td></td>';
1123
-				print '<td></td>';
1124
-				print '<td></td>';
1125
-				if (! $disablemove) print '<td></td>';
1126
-				print "</tr>\n";
1127
-			}
1128
-
1129
-			print '<tr class="liste_titre nodrag nodrop">';
1130
-			//print $url.' sortfield='.$sortfield.' sortorder='.$sortorder;
1131
-			print_liste_field_titre('Documents2',$url,"name","",$param,'align="left"',$sortfield,$sortorder);
1132
-			print_liste_field_titre('Size',$url,"size","",$param,'align="right"',$sortfield,$sortorder);
1133
-			print_liste_field_titre('Date',$url,"date","",$param,'align="center"',$sortfield,$sortorder);
1134
-			if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"');					// Preview
1135
-			print_liste_field_titre('');
1136
-			print_liste_field_titre('');
1137
-			if (! $disablemove) print_liste_field_titre('');
1138
-			print "</tr>\n";
1139
-
1140
-			// Get list of files stored into database for same relative directory
1141
-			if ($relativedir)
1142
-			{
1143
-				completeFileArrayWithDatabaseInfo($filearray, $relativedir);
1144
-
1145
-				//var_dump($sortfield.' - '.$sortorder);
1146
-				if ($sortfield && $sortorder)	// If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1147
-				{
1148
-					$filearray=dol_sort_array($filearray, $sortfield, $sortorder);
1149
-				}
1150
-			}
1151
-
1152
-			$nboffiles=count($filearray);
1153
-			if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1154
-
1155
-			$i=0; $nboflines = 0; $lastrowid=0;
1156
-			foreach($filearray as $key => $file)      // filearray must be only files here
1157
-			{
1158
-				if ($file['name'] != '.'
1159
-						&& $file['name'] != '..'
1160
-						&& ! preg_match('/\.meta$/i',$file['name']))
1161
-				{
1162
-					if ($filearray[$key]['rowid'] > 0) $lastrowid = $filearray[$key]['rowid'];
1163
-					$filepath=$relativepath.$file['name'];
1164
-
1165
-					$editline=0;
1166
-					$nboflines++;
1167
-					print '<!-- Line list_of_documents '.$key.' relativepath = '.$relativepath.' -->'."\n";
1168
-					// Do we have entry into database ?
1169
-					print '<!-- In database: position='.$filearray[$key]['position'].' -->'."\n";
1170
-					print '<tr class="oddeven" id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'AFTER'.$lastrowid.'POS'.($i+1)).'">';
1171
-
1172
-					// File name
1173
-					print '<td class="minwith200">';
1174
-
1175
-					// Show file name with link to download
1176
-					//print "XX".$file['name'];	//$file['name'] must be utf8
1177
-					print '<a class="paddingright" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1178
-					if ($forcedownload) print '&attachment=1';
1179
-					if (! empty($object->entity)) print '&entity='.$object->entity;
1180
-					print '&file='.urlencode($filepath);
1181
-					print '">';
1182
-					print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'],0,0).')', 'inline-block valignbottom paddingright');
1183
-					if ($showrelpart == 1) print $relativepath;
1184
-					//print dol_trunc($file['name'],$maxlength,'middle');
1185
-					if (GETPOST('action','aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile','alpha')))
1186
-					{
1187
-						print '</a>';
1188
-						$section_dir=dirname(GETPOST('urlfile','alpha'));
1189
-						print '<input type="hidden" name="section_dir" value="'.$section_dir.'">';
1190
-						print '<input type="hidden" name="renamefilefrom" value="'.dol_escape_htmltag($file['name']).'">';
1191
-						print '<input type="text" name="renamefileto" class="quatrevingtpercent" value="'.dol_escape_htmltag($file['name']).'">';
1192
-						$editline=1;
1193
-					}
1194
-					else
1195
-					{
1196
-						print dol_trunc($file['name'], 200);
1197
-						print '</a>';
1198
-					}
1199
-					// Preview link
1200
-					if (! $editline) print $this->showPreview($file, $modulepart, $filepath);
1201
-					// Public share link
1202
-					//if (! $editline && ! empty($filearray[$key]['hashp'])) print pictowithlinktodirectdownload;
1203
-
1204
-					print "</td>\n";
1205
-
1206
-					// Size
1207
-					$sizetoshow = dol_print_size($file['size'],1,1);
1208
-					$sizetoshowbytes = dol_print_size($file['size'],0,1);
1209
-
1210
-					print '<td align="right" width="80px">';
1211
-					if ($sizetoshow == $sizetoshowbytes) print $sizetoshow;
1212
-					else {
1213
-						print $form->textwithpicto($sizetoshow, $sizetoshowbytes, -1);
1214
-					}
1215
-					print '</td>';
1216
-
1217
-					// Date
1218
-					print '<td align="center" width="140px">'.dol_print_date($file['date'],"dayhour","tzuser").'</td>';	// 140px = width for date with PM format
1219
-
1220
-					// Preview
1221
-					if (empty($useinecm))
1222
-					{
1223
-						$fileinfo = pathinfo($file['name']);
1224
-						print '<td align="center">';
1225
-						if (image_format_supported($file['name']) > 0)
1226
-						{
1227
-							$minifile=getImageFileNameForSize($file['name'], '_mini'); // For new thumbs using same ext (in lower case howerver) than original
1228
-							if (! dol_is_file($file['path'].'/'.$minifile)) $minifile=getImageFileNameForSize($file['name'], '_mini', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
1229
-							//print $file['path'].'/'.$minifile.'<br>';
1230
-
1231
-							$urlforhref=getAdvancedPreviewUrl($modulepart, $relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity)?$object->entity:$conf->entity));
1232
-							if (empty($urlforhref)) {
1233
-								$urlforhref=DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity)?$object->entity:$conf->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
1234
-								print '<a href="'.$urlforhref.'" class="aphoto" target="_blank">';
1235
-							} else {
1236
-								print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
1237
-							}
1238
-							print '<img border="0" height="'.$maxheightmini.'" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity)?$object->entity:$conf->entity).'&file='.urlencode($relativepath.$minifile).'" title="">';
1239
-							print '</a>';
1240
-						}
1241
-						else print '&nbsp;';
1242
-						print '</td>';
1243
-					}
1244
-
1245
-					// Hash of file (only if we are in a mode where a scan of dir were done and we have id of file in ECM table)
1246
-					print '<td align="center">';
1247
-					if ($relativedir && $filearray[$key]['rowid'] > 0)
1248
-					{
1249
-						if ($editline)
1250
-						{
1251
-							print $langs->trans("FileSharedViaALink").' ';
1252
-							print '<input class="inline-block" type="checkbox" name="shareenabled"'.($file['share']?' checked="checked"':'').' /> ';
1253
-						}
1254
-						else
1255
-						{
1256
-							if ($file['share'])
1257
-							{
1258
-								// Define $urlwithroot
1259
-								$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
1260
-								$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
1261
-								//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
1262
-
1263
-								//print '<span class="opacitymedium">'.$langs->trans("Hash").' : '.$file['share'].'</span>';
1264
-								$forcedownload=0;
1265
-								$paramlink='';
1266
-								if (! empty($file['share'])) $paramlink.=($paramlink?'&':'').'hashp='.$file['share'];			// Hash for public share
1267
-								if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1';
1268
-
1269
-								$fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:'');
1270
-
1271
-								print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' ';
1272
-								print '<input type="text" class="quatrevingtpercent" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
1273
-							}
1274
-							else
1275
-							{
1276
-								//print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
1277
-							}
1278
-						}
1279
-					}
1280
-					print '</td>';
1281
-
1282
-					// Actions buttons
1283
-					if (! $editline)
1284
-					{
1285
-						// Delete or view link
1286
-						// ($param must start with &)
1287
-						print '<td class="valignmiddle right actionbuttons"><!-- action on files -->';
1288
-						if ($useinecm == 1)
1289
-						{
1290
-							print '<a href="'.DOL_URL_ROOT.'/ecm/file_card.php?urlfile='.urlencode($file['name']).$param.'" class="editfilelink" rel="'.urlencode($file['name']).'">'.img_edit('default', 0, 'class="paddingrightonly"').'</a>';
1291
-						}
1292
-						if (! $useinecm || $useinecm == 2)
1293
-						{
1294
-							$newmodulepart=$modulepart;
1295
-							if (in_array($modulepart, array('product','produit','service'))) $newmodulepart='produit|service';
1296
-
1297
-							if (! $disablecrop && image_format_supported($file['name']) > 0)
1298
-							{
1299
-								if ($permtoeditline)
1300
-								{
1301
-	   								// Link to resize
1302
-	   						   		print '<a href="'.DOL_URL_ROOT.'/core/photos_resize.php?modulepart='.urlencode($newmodulepart).'&id='.$object->id.'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension'])).'" title="'.dol_escape_htmltag($langs->trans("ResizeOrCrop")).'">'.img_picto($langs->trans("ResizeOrCrop"),'resize','class="paddingrightonly"').'</a>';
1303
-								}
1304
-							}
1305
-
1306
-							if ($permtoeditline)
1307
-							{
1308
-								$paramsectiondir=(in_array($modulepart, array('medias','ecm'))?'&section_dir='.urlencode($relativepath):'');
1309
-								print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$paramsectiondir.$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
1310
-							}
1311
-						}
1312
-						if ($permonobject)
1313
-						{
1314
-							$useajax=1;
1315
-							if (! empty($conf->dol_use_jmobile)) $useajax=0;
1316
-							if (empty($conf->use_javascript_ajax)) $useajax=0;
1317
-							if (! empty($conf->global->MAIN_ECM_DISABLE_JS)) $useajax=0;
1318
-							print '<a href="'.(($useinecm && $useajax)?'#':($url.'?action=delete&urlfile='.urlencode($filepath).$param)).'" class="deletefilelink" rel="'.$filepath.'">'.img_delete().'</a>';
1319
-						}
1320
-						print "</td>";
1024
+        global $user, $conf, $langs, $hookmanager;
1025
+        global $sortfield, $sortorder, $maxheightmini;
1026
+        global $dolibarr_main_url_root;
1027
+        global $form;
1028
+
1029
+        $disablecrop=1;
1030
+        if (in_array($modulepart, array('expensereport','holiday','member','project','product','produit','service','societe','tax','ticket','user'))) $disablecrop=0;
1031
+
1032
+        // Define relative path used to store the file
1033
+        if (empty($relativepath))
1034
+        {
1035
+            $relativepath=(! empty($object->ref)?dol_sanitizeFileName($object->ref):'').'/';
1036
+            if ($object->element == 'invoice_supplier') $relativepath=get_exdir($object->id,2,0,0,$object,'invoice_supplier').$relativepath;	// TODO Call using a defined value for $relativepath
1037
+            if ($object->element == 'project_task') $relativepath='Call_not_supported_._Call_function_using_a_defined_relative_path_.';
1038
+        }
1039
+        // For backward compatiblity, we detect file stored into an old path
1040
+        if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $filearray[0]['level1name'] == 'photos')
1041
+        {
1042
+            $relativepath=preg_replace('/^.*\/produit\//','',$filearray[0]['path']).'/';
1043
+        }
1044
+        // Defined relative dir to DOL_DATA_ROOT
1045
+        $relativedir = '';
1046
+        if ($upload_dir)
1047
+        {
1048
+            $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir);
1049
+            $relativedir = preg_replace('/^[\\/]/','',$relativedir);
1050
+        }
1051
+
1052
+        $hookmanager->initHooks(array('formfile'));
1053
+        $parameters=array(
1054
+                'filearray' => $filearray,
1055
+                'modulepart'=> $modulepart,
1056
+                'param' => $param,
1057
+                'forcedownload' => $forcedownload,
1058
+                'relativepath' => $relativepath,    // relative filename to module dir
1059
+                'relativedir' => $relativedir,      // relative dirname to DOL_DATA_ROOT
1060
+                'permtodelete' => $permonobject,
1061
+                'useinecm' => $useinecm,
1062
+                'textifempty' => $textifempty,
1063
+                'maxlength' => $maxlength,
1064
+                'title' => $title,
1065
+                'url' => $url
1066
+        );
1067
+        $reshook=$hookmanager->executeHooks('showFilesList', $parameters, $object);
1068
+
1069
+        if (isset($reshook) && $reshook != '') // null or '' for bypass
1070
+        {
1071
+            return $reshook;
1072
+        }
1073
+        else
1074
+        {
1075
+            if (! is_object($form))
1076
+            {
1077
+                include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';		// The compoent may be included into ajax page that does not include the Form class
1078
+                $form=new Form($this->db);
1079
+            }
1321 1080
 
1322
-						if (empty($disablemove))
1323
-						{
1324
-							if ($nboffiles > 1 && $conf->browser->layout != 'phone') {
1325
-								print '<td align="center" class="linecolmove tdlineupdown">';
1326
-								if ($i > 0) {
1327
-									print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=up&amp;rowid='.$line->id.'">'.img_up('default',0,'imgupforline').'</a>';
1328
-								}
1329
-								if ($i < $nboffiles-1) {
1330
-									print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=down&amp;rowid='.$line->id.'">'.img_down('default',0,'imgdownforline').'</a>';
1331
-								}
1332
-								print '</td>';
1333
-							}
1334
-							else {
1335
-							   	print '<td align="center"'.(($conf->browser->layout != 'phone' && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"').'>';
1336
-							   	print '</td>';
1337
-							}
1338
-					   }
1339
-					}
1340
-					else
1341
-					{
1342
-						print '<td class="right">';
1343
-						print '<input type="hidden" name="ecmfileid" value="'.$filearray[$key]['rowid'].'">';
1344
-						print '<input type="submit" class="button" name="renamefilesave" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
1345
-						print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
1346
-						print '</td>';
1347
-						if (empty($disablemove)) print '<td class="right"></td>';
1348
-					}
1349
-					print "</tr>\n";
1350
-
1351
-					$i++;
1352
-				}
1353
-			}
1354
-			if ($nboffiles == 0)
1355
-			{
1356
-				$colspan=(empty($useinecm)?'6':'6');
1357
-				if (empty($disablemove)) $colspan++;		// 6 columns or 7
1358
-				print '<tr class="oddeven"><td colspan="'.$colspan.'" class="opacitymedium">';
1359
-				if (empty($textifempty)) print $langs->trans("NoFileFound");
1360
-				else print $textifempty;
1361
-				print '</td></tr>';
1362
-			}
1363
-			print "</table>";
1364
-			print '</div>';
1365
-
1366
-			if ($nboflines > 1 && is_object($object)) {
1367
-				if (! empty($conf->use_javascript_ajax) && $permtoeditline) {
1368
-					$table_element_line = 'ecm_files';
1369
-					include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
1370
-				}
1371
-			}
1372
-
1373
-			print ajax_autoselect('downloadlink');
1374
-
1375
-			if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline)
1376
-			{
1377
-				print '</form>';
1378
-			}
1379
-
1380
-			return $nboffiles;
1381
-		}
1382
-	}
1081
+            if (! preg_match('/&id=/', $param) && isset($object->id)) $param.='&id='.$object->id;
1082
+            $relativepathwihtoutslashend=preg_replace('/\/$/', '', $relativepath);
1083
+            if ($relativepathwihtoutslashend) $param.= '&file='.urlencode($relativepathwihtoutslashend);
1084
+
1085
+            if ($permtoeditline < 0)  // Old behaviour for backward compatibility. New feature should call method with value 0 or 1
1086
+            {
1087
+                $permtoeditline=0;
1088
+                if (in_array($modulepart, array('product','produit','service')))
1089
+                {
1090
+                    if ($user->rights->produit->creer && $object->type == Product::TYPE_PRODUCT) $permtoeditline=1;
1091
+                    if ($user->rights->service->creer && $object->type == Product::TYPE_SERVICE) $permtoeditline=1;
1092
+                }
1093
+            }
1094
+            if (empty($conf->global->MAIN_UPLOAD_DOC))
1095
+            {
1096
+                $permtoeditline=0;
1097
+                $permonobject=0;
1098
+            }
1099
+
1100
+            // Show list of existing files
1101
+            if (empty($useinecm) && $title != 'none') print load_fiche_titre($title?$title:$langs->trans("AttachedFiles"));
1102
+            if (empty($url)) $url=$_SERVER["PHP_SELF"];
1103
+
1104
+            print '<!-- html.formfile::list_of_documents -->'."\n";
1105
+            if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline)
1106
+            {
1107
+                print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param.'" method="POST">';
1108
+                print '<input type="hidden" name="action" value="renamefile">';
1109
+                print '<input type="hidden" name="id" value="'.$object->id.'">';
1110
+                print '<input type="hidden" name="modulepart" value="'.$modulepart.'">';
1111
+            }
1112
+
1113
+            print '<div class="div-table-responsive-no-min">';
1114
+            print '<table width="100%" id="tablelines" class="'.($useinecm?'liste noborder':'liste').'">'."\n";
1115
+
1116
+            if (! empty($addfilterfields))
1117
+            {
1118
+                print '<tr class="liste_titre nodrag nodrop">';
1119
+                print '<td><input type="search_doc_ref" value="'.dol_escape_htmltag(GETPOST('search_doc_ref','alpha')).'"></td>';
1120
+                print '<td></td>';
1121
+                print '<td></td>';
1122
+                if (empty($useinecm)) print '<td></td>';
1123
+                print '<td></td>';
1124
+                print '<td></td>';
1125
+                if (! $disablemove) print '<td></td>';
1126
+                print "</tr>\n";
1127
+            }
1128
+
1129
+            print '<tr class="liste_titre nodrag nodrop">';
1130
+            //print $url.' sortfield='.$sortfield.' sortorder='.$sortorder;
1131
+            print_liste_field_titre('Documents2',$url,"name","",$param,'align="left"',$sortfield,$sortorder);
1132
+            print_liste_field_titre('Size',$url,"size","",$param,'align="right"',$sortfield,$sortorder);
1133
+            print_liste_field_titre('Date',$url,"date","",$param,'align="center"',$sortfield,$sortorder);
1134
+            if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"');					// Preview
1135
+            print_liste_field_titre('');
1136
+            print_liste_field_titre('');
1137
+            if (! $disablemove) print_liste_field_titre('');
1138
+            print "</tr>\n";
1139
+
1140
+            // Get list of files stored into database for same relative directory
1141
+            if ($relativedir)
1142
+            {
1143
+                completeFileArrayWithDatabaseInfo($filearray, $relativedir);
1144
+
1145
+                //var_dump($sortfield.' - '.$sortorder);
1146
+                if ($sortfield && $sortorder)	// If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
1147
+                {
1148
+                    $filearray=dol_sort_array($filearray, $sortfield, $sortorder);
1149
+                }
1150
+            }
1151
+
1152
+            $nboffiles=count($filearray);
1153
+            if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1154
+
1155
+            $i=0; $nboflines = 0; $lastrowid=0;
1156
+            foreach($filearray as $key => $file)      // filearray must be only files here
1157
+            {
1158
+                if ($file['name'] != '.'
1159
+                        && $file['name'] != '..'
1160
+                        && ! preg_match('/\.meta$/i',$file['name']))
1161
+                {
1162
+                    if ($filearray[$key]['rowid'] > 0) $lastrowid = $filearray[$key]['rowid'];
1163
+                    $filepath=$relativepath.$file['name'];
1164
+
1165
+                    $editline=0;
1166
+                    $nboflines++;
1167
+                    print '<!-- Line list_of_documents '.$key.' relativepath = '.$relativepath.' -->'."\n";
1168
+                    // Do we have entry into database ?
1169
+                    print '<!-- In database: position='.$filearray[$key]['position'].' -->'."\n";
1170
+                    print '<tr class="oddeven" id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'AFTER'.$lastrowid.'POS'.($i+1)).'">';
1171
+
1172
+                    // File name
1173
+                    print '<td class="minwith200">';
1174
+
1175
+                    // Show file name with link to download
1176
+                    //print "XX".$file['name'];	//$file['name'] must be utf8
1177
+                    print '<a class="paddingright" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1178
+                    if ($forcedownload) print '&attachment=1';
1179
+                    if (! empty($object->entity)) print '&entity='.$object->entity;
1180
+                    print '&file='.urlencode($filepath);
1181
+                    print '">';
1182
+                    print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'],0,0).')', 'inline-block valignbottom paddingright');
1183
+                    if ($showrelpart == 1) print $relativepath;
1184
+                    //print dol_trunc($file['name'],$maxlength,'middle');
1185
+                    if (GETPOST('action','aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile','alpha')))
1186
+                    {
1187
+                        print '</a>';
1188
+                        $section_dir=dirname(GETPOST('urlfile','alpha'));
1189
+                        print '<input type="hidden" name="section_dir" value="'.$section_dir.'">';
1190
+                        print '<input type="hidden" name="renamefilefrom" value="'.dol_escape_htmltag($file['name']).'">';
1191
+                        print '<input type="text" name="renamefileto" class="quatrevingtpercent" value="'.dol_escape_htmltag($file['name']).'">';
1192
+                        $editline=1;
1193
+                    }
1194
+                    else
1195
+                    {
1196
+                        print dol_trunc($file['name'], 200);
1197
+                        print '</a>';
1198
+                    }
1199
+                    // Preview link
1200
+                    if (! $editline) print $this->showPreview($file, $modulepart, $filepath);
1201
+                    // Public share link
1202
+                    //if (! $editline && ! empty($filearray[$key]['hashp'])) print pictowithlinktodirectdownload;
1203
+
1204
+                    print "</td>\n";
1205
+
1206
+                    // Size
1207
+                    $sizetoshow = dol_print_size($file['size'],1,1);
1208
+                    $sizetoshowbytes = dol_print_size($file['size'],0,1);
1209
+
1210
+                    print '<td align="right" width="80px">';
1211
+                    if ($sizetoshow == $sizetoshowbytes) print $sizetoshow;
1212
+                    else {
1213
+                        print $form->textwithpicto($sizetoshow, $sizetoshowbytes, -1);
1214
+                    }
1215
+                    print '</td>';
1216
+
1217
+                    // Date
1218
+                    print '<td align="center" width="140px">'.dol_print_date($file['date'],"dayhour","tzuser").'</td>';	// 140px = width for date with PM format
1219
+
1220
+                    // Preview
1221
+                    if (empty($useinecm))
1222
+                    {
1223
+                        $fileinfo = pathinfo($file['name']);
1224
+                        print '<td align="center">';
1225
+                        if (image_format_supported($file['name']) > 0)
1226
+                        {
1227
+                            $minifile=getImageFileNameForSize($file['name'], '_mini'); // For new thumbs using same ext (in lower case howerver) than original
1228
+                            if (! dol_is_file($file['path'].'/'.$minifile)) $minifile=getImageFileNameForSize($file['name'], '_mini', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
1229
+                            //print $file['path'].'/'.$minifile.'<br>';
1230
+
1231
+                            $urlforhref=getAdvancedPreviewUrl($modulepart, $relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity)?$object->entity:$conf->entity));
1232
+                            if (empty($urlforhref)) {
1233
+                                $urlforhref=DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity)?$object->entity:$conf->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
1234
+                                print '<a href="'.$urlforhref.'" class="aphoto" target="_blank">';
1235
+                            } else {
1236
+                                print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
1237
+                            }
1238
+                            print '<img border="0" height="'.$maxheightmini.'" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity)?$object->entity:$conf->entity).'&file='.urlencode($relativepath.$minifile).'" title="">';
1239
+                            print '</a>';
1240
+                        }
1241
+                        else print '&nbsp;';
1242
+                        print '</td>';
1243
+                    }
1244
+
1245
+                    // Hash of file (only if we are in a mode where a scan of dir were done and we have id of file in ECM table)
1246
+                    print '<td align="center">';
1247
+                    if ($relativedir && $filearray[$key]['rowid'] > 0)
1248
+                    {
1249
+                        if ($editline)
1250
+                        {
1251
+                            print $langs->trans("FileSharedViaALink").' ';
1252
+                            print '<input class="inline-block" type="checkbox" name="shareenabled"'.($file['share']?' checked="checked"':'').' /> ';
1253
+                        }
1254
+                        else
1255
+                        {
1256
+                            if ($file['share'])
1257
+                            {
1258
+                                // Define $urlwithroot
1259
+                                $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
1260
+                                $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
1261
+                                //$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
1262
+
1263
+                                //print '<span class="opacitymedium">'.$langs->trans("Hash").' : '.$file['share'].'</span>';
1264
+                                $forcedownload=0;
1265
+                                $paramlink='';
1266
+                                if (! empty($file['share'])) $paramlink.=($paramlink?'&':'').'hashp='.$file['share'];			// Hash for public share
1267
+                                if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1';
1268
+
1269
+                                $fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:'');
1270
+
1271
+                                print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' ';
1272
+                                print '<input type="text" class="quatrevingtpercent" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
1273
+                            }
1274
+                            else
1275
+                            {
1276
+                                //print '<span class="opacitymedium">'.$langs->trans("FileNotShared").'</span>';
1277
+                            }
1278
+                        }
1279
+                    }
1280
+                    print '</td>';
1281
+
1282
+                    // Actions buttons
1283
+                    if (! $editline)
1284
+                    {
1285
+                        // Delete or view link
1286
+                        // ($param must start with &)
1287
+                        print '<td class="valignmiddle right actionbuttons"><!-- action on files -->';
1288
+                        if ($useinecm == 1)
1289
+                        {
1290
+                            print '<a href="'.DOL_URL_ROOT.'/ecm/file_card.php?urlfile='.urlencode($file['name']).$param.'" class="editfilelink" rel="'.urlencode($file['name']).'">'.img_edit('default', 0, 'class="paddingrightonly"').'</a>';
1291
+                        }
1292
+                        if (! $useinecm || $useinecm == 2)
1293
+                        {
1294
+                            $newmodulepart=$modulepart;
1295
+                            if (in_array($modulepart, array('product','produit','service'))) $newmodulepart='produit|service';
1296
+
1297
+                            if (! $disablecrop && image_format_supported($file['name']) > 0)
1298
+                            {
1299
+                                if ($permtoeditline)
1300
+                                {
1301
+                                        // Link to resize
1302
+                                            print '<a href="'.DOL_URL_ROOT.'/core/photos_resize.php?modulepart='.urlencode($newmodulepart).'&id='.$object->id.'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension'])).'" title="'.dol_escape_htmltag($langs->trans("ResizeOrCrop")).'">'.img_picto($langs->trans("ResizeOrCrop"),'resize','class="paddingrightonly"').'</a>';
1303
+                                }
1304
+                            }
1305
+
1306
+                            if ($permtoeditline)
1307
+                            {
1308
+                                $paramsectiondir=(in_array($modulepart, array('medias','ecm'))?'&section_dir='.urlencode($relativepath):'');
1309
+                                print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$paramsectiondir.$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
1310
+                            }
1311
+                        }
1312
+                        if ($permonobject)
1313
+                        {
1314
+                            $useajax=1;
1315
+                            if (! empty($conf->dol_use_jmobile)) $useajax=0;
1316
+                            if (empty($conf->use_javascript_ajax)) $useajax=0;
1317
+                            if (! empty($conf->global->MAIN_ECM_DISABLE_JS)) $useajax=0;
1318
+                            print '<a href="'.(($useinecm && $useajax)?'#':($url.'?action=delete&urlfile='.urlencode($filepath).$param)).'" class="deletefilelink" rel="'.$filepath.'">'.img_delete().'</a>';
1319
+                        }
1320
+                        print "</td>";
1321
+
1322
+                        if (empty($disablemove))
1323
+                        {
1324
+                            if ($nboffiles > 1 && $conf->browser->layout != 'phone') {
1325
+                                print '<td align="center" class="linecolmove tdlineupdown">';
1326
+                                if ($i > 0) {
1327
+                                    print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=up&amp;rowid='.$line->id.'">'.img_up('default',0,'imgupforline').'</a>';
1328
+                                }
1329
+                                if ($i < $nboffiles-1) {
1330
+                                    print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=down&amp;rowid='.$line->id.'">'.img_down('default',0,'imgdownforline').'</a>';
1331
+                                }
1332
+                                print '</td>';
1333
+                            }
1334
+                            else {
1335
+                                    print '<td align="center"'.(($conf->browser->layout != 'phone' && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"').'>';
1336
+                                    print '</td>';
1337
+                            }
1338
+                        }
1339
+                    }
1340
+                    else
1341
+                    {
1342
+                        print '<td class="right">';
1343
+                        print '<input type="hidden" name="ecmfileid" value="'.$filearray[$key]['rowid'].'">';
1344
+                        print '<input type="submit" class="button" name="renamefilesave" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
1345
+                        print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
1346
+                        print '</td>';
1347
+                        if (empty($disablemove)) print '<td class="right"></td>';
1348
+                    }
1349
+                    print "</tr>\n";
1350
+
1351
+                    $i++;
1352
+                }
1353
+            }
1354
+            if ($nboffiles == 0)
1355
+            {
1356
+                $colspan=(empty($useinecm)?'6':'6');
1357
+                if (empty($disablemove)) $colspan++;		// 6 columns or 7
1358
+                print '<tr class="oddeven"><td colspan="'.$colspan.'" class="opacitymedium">';
1359
+                if (empty($textifempty)) print $langs->trans("NoFileFound");
1360
+                else print $textifempty;
1361
+                print '</td></tr>';
1362
+            }
1363
+            print "</table>";
1364
+            print '</div>';
1365
+
1366
+            if ($nboflines > 1 && is_object($object)) {
1367
+                if (! empty($conf->use_javascript_ajax) && $permtoeditline) {
1368
+                    $table_element_line = 'ecm_files';
1369
+                    include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
1370
+                }
1371
+            }
1372
+
1373
+            print ajax_autoselect('downloadlink');
1374
+
1375
+            if (GETPOST('action','aZ09') == 'editfile' && $permtoeditline)
1376
+            {
1377
+                print '</form>';
1378
+            }
1379
+
1380
+            return $nboffiles;
1381
+        }
1382
+    }
1383 1383
 
1384 1384
 
1385 1385
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1386
-	/**
1387
-	 *	Show list of documents in a directory
1388
-	 *
1389
-	 *  @param	string	$upload_dir         Directory that was scanned
1390
-	 *  @param  array	$filearray          Array of files loaded by dol_dir_list function before calling this function
1391
-	 *  @param  string	$modulepart         Value for modulepart used by download wrapper
1392
-	 *  @param  string	$param              Parameters on sort links
1393
-	 *  @param  int		$forcedownload      Force to open dialog box "Save As" when clicking on file
1394
-	 *  @param  string	$relativepath       Relative path of docs (autodefined if not provided)
1395
-	 *  @param  int		$permtodelete       Permission to delete
1396
-	 *  @param  int		$useinecm           Change output for use in ecm module
1397
-	 *  @param  int		$textifempty        Text to show if filearray is empty
1398
-	 *  @param  int		$maxlength          Maximum length of file name shown
1399
-	 *  @param	string 	$url				Full url to use for click links ('' = autodetect)
1400
-	 *  @param	int		$addfilterfields	Add line with filters
1401
-	 *  @return int                 		<0 if KO, nb of files shown if OK
1402
-	 *  @see list_of_documents
1403
-	 */
1404
-	function list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload=0, $relativepath='', $permtodelete=1, $useinecm=0, $textifempty='', $maxlength=0, $url='', $addfilterfields=0)
1405
-	{
1386
+    /**
1387
+     *	Show list of documents in a directory
1388
+     *
1389
+     *  @param	string	$upload_dir         Directory that was scanned
1390
+     *  @param  array	$filearray          Array of files loaded by dol_dir_list function before calling this function
1391
+     *  @param  string	$modulepart         Value for modulepart used by download wrapper
1392
+     *  @param  string	$param              Parameters on sort links
1393
+     *  @param  int		$forcedownload      Force to open dialog box "Save As" when clicking on file
1394
+     *  @param  string	$relativepath       Relative path of docs (autodefined if not provided)
1395
+     *  @param  int		$permtodelete       Permission to delete
1396
+     *  @param  int		$useinecm           Change output for use in ecm module
1397
+     *  @param  int		$textifempty        Text to show if filearray is empty
1398
+     *  @param  int		$maxlength          Maximum length of file name shown
1399
+     *  @param	string 	$url				Full url to use for click links ('' = autodetect)
1400
+     *  @param	int		$addfilterfields	Add line with filters
1401
+     *  @return int                 		<0 if KO, nb of files shown if OK
1402
+     *  @see list_of_documents
1403
+     */
1404
+    function list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload=0, $relativepath='', $permtodelete=1, $useinecm=0, $textifempty='', $maxlength=0, $url='', $addfilterfields=0)
1405
+    {
1406 1406
         // phpcs:enable
1407
-		global $user, $conf, $langs, $form;
1408
-		global $sortfield, $sortorder;
1409
-		global $search_doc_ref;
1410
-
1411
-		dol_syslog(get_class($this).'::list_of_autoecmfiles upload_dir='.$upload_dir.' modulepart='.$modulepart);
1412
-
1413
-		// Show list of documents
1414
-		if (empty($useinecm)) print load_fiche_titre($langs->trans("AttachedFiles"));
1415
-		if (empty($url)) $url=$_SERVER["PHP_SELF"];
1416
-
1417
-		if (! empty($addfilterfields))
1418
-		{
1419
-			print '<form action="'.$_SERVER['PHP_SELF'].'">';
1420
-			print '<input type="hidden" name="module" value="'.$modulepart.'">';
1421
-		}
1422
-
1423
-		print '<div class="div-table-responsive-no-min">';
1424
-		print '<table width="100%" class="noborder">'."\n";
1425
-
1426
-		if (! empty($addfilterfields))
1427
-		{
1428
-			print '<tr class="liste_titre nodrag nodrop">';
1429
-			print '<td></td>';
1430
-			print '<td><input type="text" class="maxwidth100onsmartphone" name="search_doc_ref" value="'.dol_escape_htmltag($search_doc_ref).'"></td>';
1431
-			print '<td></td>';
1432
-			print '<td></td>';
1433
-			// Action column
1434
-			print '<td class="liste_titre" align="middle">';
1435
-			$searchpicto=$form->showFilterButtons();
1436
-			print $searchpicto;
1437
-			print '</td>';
1438
-			print "</tr>\n";
1439
-		}
1440
-
1441
-		print '<tr class="liste_titre">';
1442
-		$sortref="fullname";
1443
-		if ($modulepart == 'invoice_supplier') $sortref='level1name';
1444
-		print_liste_field_titre("Ref",$url,$sortref,"",$param,'align="left"',$sortfield,$sortorder);
1445
-		print_liste_field_titre("Documents2",$url,"name","",$param,'align="left"',$sortfield,$sortorder);
1446
-		print_liste_field_titre("Size",$url,"size","",$param,'align="right"',$sortfield,$sortorder);
1447
-		print_liste_field_titre("Date",$url,"date","",$param,'align="center"',$sortfield,$sortorder);
1448
-		print_liste_field_titre('','','');
1449
-		print '</tr>'."\n";
1450
-
1451
-		// To show ref or specific information according to view to show (defined by $module)
1452
-		if ($modulepart == 'company')
1453
-		{
1454
-			include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1455
-			$object_instance=new Societe($this->db);
1456
-		}
1457
-		else if ($modulepart == 'invoice')
1458
-		{
1459
-			include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1460
-			$object_instance=new Facture($this->db);
1461
-		}
1462
-		else if ($modulepart == 'invoice_supplier')
1463
-		{
1464
-			include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
1465
-			$object_instance=new FactureFournisseur($this->db);
1466
-		}
1467
-		else if ($modulepart == 'propal')
1468
-		{
1469
-			include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
1470
-			$object_instance=new Propal($this->db);
1471
-		}
1472
-		else if ($modulepart == 'supplier_proposal')
1473
-		{
1474
-			include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
1475
-			$object_instance=new SupplierProposal($this->db);
1476
-		}
1477
-		else if ($modulepart == 'order')
1478
-		{
1479
-			include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
1480
-			$object_instance=new Commande($this->db);
1481
-		}
1482
-		else if ($modulepart == 'order_supplier')
1483
-		{
1484
-			include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
1485
-			$object_instance=new CommandeFournisseur($this->db);
1486
-		}
1487
-		else if ($modulepart == 'contract')
1488
-		{
1489
-			include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
1490
-			$object_instance=new Contrat($this->db);
1491
-		}
1492
-		else if ($modulepart == 'product')
1493
-		{
1494
-			include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1495
-			$object_instance=new Product($this->db);
1496
-		}
1497
-		else if ($modulepart == 'tax')
1498
-		{
1499
-			include_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
1500
-			$object_instance=new ChargeSociales($this->db);
1501
-		}
1502
-		else if ($modulepart == 'project')
1503
-		{
1504
-			include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1505
-			$object_instance=new Project($this->db);
1506
-		}
1507
-		else if ($modulepart == 'fichinter')
1508
-		{
1509
-			include_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
1510
-			$object_instance=new Fichinter($this->db);
1511
-		}
1512
-		else if ($modulepart == 'user')
1513
-		{
1514
-			include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1515
-			$object_instance=new User($this->db);
1516
-		}
1517
-		else if ($modulepart == 'expensereport')
1518
-		{
1519
-			include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
1520
-			$object_instance=new ExpenseReport($this->db);
1521
-		}
1522
-		else if ($modulepart == 'holiday')
1523
-		{
1524
-			include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
1525
-			$object_instance=new Holiday($this->db);
1526
-		}
1527
-
1528
-		foreach($filearray as $key => $file)
1529
-		{
1530
-			if (!is_dir($file['name'])
1531
-			&& $file['name'] != '.'
1532
-			&& $file['name'] != '..'
1533
-			&& $file['name'] != 'CVS'
1534
-			&& ! preg_match('/\.meta$/i',$file['name']))
1535
-			{
1536
-				// Define relative path used to store the file
1537
-				$relativefile=preg_replace('/'.preg_quote($upload_dir.'/','/').'/','',$file['fullname']);
1538
-
1539
-				//var_dump($file);
1540
-				$id=0; $ref=''; $label='';
1541
-
1542
-				// To show ref or specific information according to view to show (defined by $module)
1543
-				if ($modulepart == 'company')           { preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:''); }
1544
-				if ($modulepart == 'invoice')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1545
-				if ($modulepart == 'invoice_supplier')  { preg_match('/([^\/]+)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); if (is_numeric($ref)) { $id=$ref; $ref=''; } }	// $ref may be also id with old supplier invoices
1546
-				if ($modulepart == 'propal')            { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1547
-				if ($modulepart == 'supplier_proposal') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1548
-				if ($modulepart == 'order')             { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1549
-				if ($modulepart == 'order_supplier')    { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1550
-				if ($modulepart == 'contract')          { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1551
-				if ($modulepart == 'product')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1552
-				if ($modulepart == 'tax')               { preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:''); }
1553
-				if ($modulepart == 'project')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:'');}
1554
-				if ($modulepart == 'fichinter')         { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:'');}
1555
-				if ($modulepart == 'user')              { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $id=(isset($reg[1])?$reg[1]:'');}
1556
-				if ($modulepart == 'expensereport')     { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:'');}
1557
-				if ($modulepart == 'holiday')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $id=(isset($reg[1])?$reg[1]:'');}
1558
-
1559
-				if (! $id && ! $ref) continue;
1560
-				$found=0;
1561
-				if (! empty($this->cache_objects[$modulepart.'_'.$id.'_'.$ref]))
1562
-				{
1563
-					$found=1;
1564
-				}
1565
-				else
1566
-				{
1567
-					//print 'Fetch '.$id." - ".$ref.'<br>';
1568
-
1569
-					if ($id) {
1570
-						$result = $object_instance->fetch($id);
1571
-					} else {
1572
-						//fetchOneLike looks for objects with wildcards in its reference.
1573
-						//It is useful for those masks who get underscores instead of their actual symbols
1574
-						//fetchOneLike requires some info in the object. If it doesn't have it, then 0 is returned
1575
-						//that's why we look only look fetchOneLike when fetch returns 0
1576
-						if (!$result = $object_instance->fetch('', $ref)) {
1577
-							$result = $object_instance->fetchOneLike($ref);
1578
-						}
1579
-					}
1580
-
1581
-					if ($result > 0) {  // Save object into a cache
1582
-						$found=1; $this->cache_objects[$modulepart.'_'.$id.'_'.$ref] = clone $object_instance;
1583
-					}
1584
-					if ($result == 0) { $found=1; $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]='notfound'; unset($filearray[$key]); }
1585
-				}
1586
-
1587
-				if (! $found > 0 || ! is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) continue;    // We do not show orphelins files
1588
-
1589
-				print '<!-- Line list_of_autoecmfiles '.$key.' -->'."\n";
1590
-				print '<tr class="oddeven">';
1591
-				print '<td>';
1592
-				if ($found > 0 && is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) print $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]->getNomUrl(1,'document');
1593
-				else print $langs->trans("ObjectDeleted",($id?$id:$ref));
1594
-
1595
-				//$modulesubdir=dol_sanitizeFileName($ref);
1596
-				$modulesubdir=dirname($relativefile);
1597
-
1598
-				//$filedir=$conf->$modulepart->dir_output . '/' . dol_sanitizeFileName($obj->ref);
1599
-				$filedir=$file['path'];
1600
-				//$urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid;
1601
-				//print $formfile->getDocumentsLink($modulepart, $filename, $filedir);
1602
-
1603
-				print '</td>';
1604
-
1605
-				// File
1606
-				print '<td>';
1607
-				//print "XX".$file['name']; //$file['name'] must be utf8
1608
-				print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1609
-				if ($forcedownload) print '&attachment=1';
1610
-				print '&file='.urlencode($relativefile).'">';
1611
-				print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')');
1612
-				print dol_trunc($file['name'],$maxlength,'middle');
1613
-				print '</a>';
1614
-
1615
-				//print $this->getDocumentsLink($modulepart, $modulesubdir, $filedir, '^'.preg_quote($file['name'],'/').'$');
1616
-				print $this->showPreview($file, $modulepart, $file['relativename']);
1617
-
1618
-				print "</td>\n";
1619
-				print '<td align="right">'.dol_print_size($file['size'],1,1).'</td>';
1620
-				print '<td align="center">'.dol_print_date($file['date'],"dayhour").'</td>';
1621
-				print '<td align="right">';
1622
-				//if (! empty($useinecm))  print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1623
-				//if ($forcedownload) print '&attachment=1';
1624
-				//print '&file='.urlencode($relativefile).'">';
1625
-				//print img_view().'</a> &nbsp; ';
1626
-				//if ($permtodelete) print '<a href="'.$url.'?id='.$object->id.'&section='.$_REQUEST["section"].'&action=delete&urlfile='.urlencode($file['name']).'">'.img_delete().'</a>';
1627
-				//else print '&nbsp;';
1628
-				print "</td></tr>\n";
1629
-			}
1630
-		}
1631
-
1632
-		if (count($filearray) == 0)
1633
-		{
1634
-			print '<tr class="oddeven"><td colspan="5">';
1635
-			if (empty($textifempty)) print $langs->trans("NoFileFound");
1636
-			else print $textifempty;
1637
-			print '</td></tr>';
1638
-		}
1639
-		print "</table>";
1640
-		print '</div>';
1641
-
1642
-		if (! empty($addfilterfields)) print '</form>';
1643
-		// Fin de zone
1644
-	}
1645
-
1646
-	/**
1647
-	 *    Show form to upload a new file with jquery fileupload.
1648
-	 *    This form use the fileupload.php file.
1649
-	 *
1650
-	 *    @param	Object	$object		Object to use
1651
-	 *    @return	void
1652
-	 */
1653
-	private function _formAjaxFileUpload($object)
1654
-	{
1655
-		global $langs, $conf;
1656
-
1657
-		// PHP post_max_size
1658
-		$post_max_size				= ini_get('post_max_size');
1659
-		$mul_post_max_size			= substr($post_max_size, -1);
1660
-		$mul_post_max_size			= ($mul_post_max_size == 'M' ? 1048576 : ($mul_post_max_size == 'K' ? 1024 : ($mul_post_max_size == 'G' ? 1073741824 : 1)));
1661
-		$post_max_size				= $mul_post_max_size * (int) $post_max_size;
1662
-		// PHP upload_max_filesize
1663
-		$upload_max_filesize		= ini_get('upload_max_filesize');
1664
-		$mul_upload_max_filesize	= substr($upload_max_filesize, -1);
1665
-		$mul_upload_max_filesize	= ($mul_upload_max_filesize == 'M' ? 1048576 : ($mul_upload_max_filesize == 'K' ? 1024 : ($mul_upload_max_filesize == 'G' ? 1073741824 : 1)));
1666
-		$upload_max_filesize		= $mul_upload_max_filesize * (int) $upload_max_filesize;
1667
-		// Max file size
1668
-		$max_file_size 				= (($post_max_size < $upload_max_filesize) ? $post_max_size : $upload_max_filesize);
1669
-
1670
-		// Include main
1671
-		include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_main.tpl.php';
1672
-
1673
-		// Include template
1674
-		include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_view.tpl.php';
1675
-	}
1676
-
1677
-	/**
1678
-	 * Show array with linked files
1679
-	 *
1680
-	 * @param 	Object		$object			Object
1681
-	 * @param 	int			$permtodelete	Deletion is allowed
1682
-	 * @param 	string		$action			Action
1683
-	 * @param 	string		$selected		???
1684
-	 * @param	string		$param			More param to add into URL
1685
-	 * @return 	int							Number of links
1686
-	 */
1687
-	public function listOfLinks($object, $permtodelete=1, $action=null, $selected=null, $param='')
1688
-	{
1689
-		global $user, $conf, $langs, $user;
1690
-		global $sortfield, $sortorder;
1691
-
1692
-		$langs->load("link");
1693
-
1694
-		require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
1695
-		$link = new Link($this->db);
1696
-		$links = array();
1697
-		if ($sortfield == "name") {
1698
-			$sortfield = "label";
1699
-		} elseif ($sortfield == "date") {
1700
-			$sortfield = "datea";
1701
-		} else {
1702
-			$sortfield = null;
1703
-		}
1704
-		$res = $link->fetchAll($links, $object->element, $object->id, $sortfield, $sortorder);
1705
-		$param .= (isset($object->id)?'&id=' . $object->id : '');
1706
-
1707
-		// Show list of associated links
1708
-		print load_fiche_titre($langs->trans("LinkedFiles"));
1709
-
1710
-		print '<form action="' . $_SERVER['PHP_SELF'] . ($param?'?'.$param:'') . '" method="POST">';
1711
-
1712
-		print '<table width="100%" class="liste">';
1713
-		print '<tr class="liste_titre">';
1714
-		print_liste_field_titre(
1715
-			$langs->trans("Links"),
1716
-			$_SERVER['PHP_SELF'],
1717
-			"name",
1718
-			"",
1719
-			$param,
1720
-			'align="left"',
1721
-			$sortfield,
1722
-			$sortorder
1723
-		);
1724
-		print_liste_field_titre(
1725
-			"",
1726
-			"",
1727
-			"",
1728
-			"",
1729
-			"",
1730
-			'align="right"'
1731
-		);
1732
-		print_liste_field_titre(
1733
-			$langs->trans("Date"),
1734
-			$_SERVER['PHP_SELF'],
1735
-			"date",
1736
-			"",
1737
-			$param,
1738
-			'align="center"',
1739
-			$sortfield,
1740
-			$sortorder
1741
-		);
1742
-		print_liste_field_titre(
1743
-			'',
1744
-			$_SERVER['PHP_SELF'],
1745
-			"",
1746
-			"",
1747
-			$param,
1748
-			'align="center"'
1749
-		);
1750
-		print_liste_field_titre('','','');
1751
-		print '</tr>';
1752
-		$nboflinks = count($links);
1753
-		if ($nboflinks > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1754
-
1755
-		foreach ($links as $link)
1756
-		{
1757
-			print '<tr class="oddeven">';
1758
-			//edit mode
1759
-			if ($action == 'update' && $selected === $link->id)
1760
-			{
1761
-				print '<td>';
1762
-				print '<input type="hidden" name="id" value="' . $object->id . '">';
1763
-				print '<input type="hidden" name="linkid" value="' . $link->id . '">';
1764
-				print '<input type="hidden" name="action" value="confirm_updateline">';
1765
-				print $langs->trans('Link') . ': <input type="text" name="link" value="' . $link->url . '">';
1766
-				print '</td>';
1767
-				print '<td>';
1768
-				print $langs->trans('Label') . ': <input type="text" name="label" value="' . $link->label . '">';
1769
-				print '</td>';
1770
-				print '<td align="center">' . dol_print_date(dol_now(), "dayhour", "tzuser") . '</td>';
1771
-				print '<td align="right"></td>';
1772
-				print '<td align="right">';
1773
-				print '<input type="submit" name="save" class="button" value="' . dol_escape_htmltag($langs->trans('Save')) . '">';
1774
-				print '<input type="submit" name="cancel" class="button" value="' . dol_escape_htmltag($langs->trans('Cancel')) . '">';
1775
-				print '</td>';
1776
-			}
1777
-			else
1778
-			{
1779
-				print '<td>';
1780
-				print img_picto('', 'object_globe').' ';
1781
-				print '<a data-ajax="false" href="' . $link->url . '" target="_blank">';
1782
-				print $link->label;
1783
-				print '</a>';
1784
-				print '</td>'."\n";
1785
-				print '<td align="right"></td>';
1786
-				print '<td align="center">' . dol_print_date($link->datea, "dayhour", "tzuser") . '</td>';
1787
-				print '<td align="center"></td>';
1788
-				print '<td align="right">';
1789
-				print '<a href="' . $_SERVER['PHP_SELF'] . '?action=update&linkid=' . $link->id . $param . '" class="editfilelink" >' . img_edit() . '</a>';	// id= is included into $param
1790
-				if ($permtodelete) {
1791
-					print ' &nbsp; <a href="'. $_SERVER['PHP_SELF'] .'?action=delete&linkid=' . $link->id . $param . '" class="deletefilelink">' . img_delete() . '</a>';	// id= is included into $param
1792
-				} else {
1793
-					print '&nbsp;';
1794
-				}
1795
-				print '</td>';
1796
-			}
1797
-			print "</tr>\n";
1798
-		}
1799
-		if ($nboflinks == 0)
1800
-		{
1801
-			print '<tr class="oddeven"><td colspan="5" class="opacitymedium">';
1802
-			print $langs->trans("NoLinkFound");
1803
-			print '</td></tr>';
1804
-		}
1805
-		print "</table>";
1806
-
1807
-		print '</form>';
1808
-
1809
-		return $nboflinks;
1810
-	}
1811
-
1812
-
1813
-	/**
1814
-	 * Show detail icon with link for preview
1815
-	 *
1816
-	 * @param   array     $file           Array with data of file. Example: array('name'=>...)
1817
-	 * @param   string    $modulepart     propal, facture, facture_fourn, ...
1818
-	 * @param   string    $relativepath   Relative path of docs
1819
-	 * @param   string    $ruleforpicto   Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file)
1820
-	 * @param	string	  $param		  More param on http links
1821
-	 * @return  string    $out            Output string with HTML
1822
-	 */
1823
-	public function showPreview($file, $modulepart, $relativepath, $ruleforpicto=0, $param='')
1824
-	{
1825
-		global $langs, $conf;
1826
-
1827
-		$out='';
1828
-		if ($conf->browser->layout != 'phone' && ! empty($conf->use_javascript_ajax))
1829
-		{
1830
-			$urladvancedpreview=getAdvancedPreviewUrl($modulepart, $relativepath, 1, $param);      // Return if a file is qualified for preview.
1831
-			if (count($urladvancedpreview))
1832
-			{
1833
-				$out.= '<a class="pictopreview '.$urladvancedpreview['css'].'" href="'.$urladvancedpreview['url'].'"'.(empty($urladvancedpreview['mime'])?'':' mime="'.$urladvancedpreview['mime'].'"').' '.(empty($urladvancedpreview['target'])?'':' target="'.$urladvancedpreview['target'].'"').'>';
1834
-				//$out.= '<a class="pictopreview">';
1835
-				if (empty($ruleforpicto))
1836
-				{
1837
-					//$out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail');
1838
-					$out.='<span class="fa fa-search-plus" style="color: gray"></span>';
1839
-				}
1840
-				else $out.= img_mime($relativepath, $langs->trans('Preview').' '.$file['name']);
1841
-				$out.= '</a>';
1842
-			}
1843
-		}
1844
-		return $out;
1845
-	}
1407
+        global $user, $conf, $langs, $form;
1408
+        global $sortfield, $sortorder;
1409
+        global $search_doc_ref;
1410
+
1411
+        dol_syslog(get_class($this).'::list_of_autoecmfiles upload_dir='.$upload_dir.' modulepart='.$modulepart);
1412
+
1413
+        // Show list of documents
1414
+        if (empty($useinecm)) print load_fiche_titre($langs->trans("AttachedFiles"));
1415
+        if (empty($url)) $url=$_SERVER["PHP_SELF"];
1416
+
1417
+        if (! empty($addfilterfields))
1418
+        {
1419
+            print '<form action="'.$_SERVER['PHP_SELF'].'">';
1420
+            print '<input type="hidden" name="module" value="'.$modulepart.'">';
1421
+        }
1422
+
1423
+        print '<div class="div-table-responsive-no-min">';
1424
+        print '<table width="100%" class="noborder">'."\n";
1425
+
1426
+        if (! empty($addfilterfields))
1427
+        {
1428
+            print '<tr class="liste_titre nodrag nodrop">';
1429
+            print '<td></td>';
1430
+            print '<td><input type="text" class="maxwidth100onsmartphone" name="search_doc_ref" value="'.dol_escape_htmltag($search_doc_ref).'"></td>';
1431
+            print '<td></td>';
1432
+            print '<td></td>';
1433
+            // Action column
1434
+            print '<td class="liste_titre" align="middle">';
1435
+            $searchpicto=$form->showFilterButtons();
1436
+            print $searchpicto;
1437
+            print '</td>';
1438
+            print "</tr>\n";
1439
+        }
1440
+
1441
+        print '<tr class="liste_titre">';
1442
+        $sortref="fullname";
1443
+        if ($modulepart == 'invoice_supplier') $sortref='level1name';
1444
+        print_liste_field_titre("Ref",$url,$sortref,"",$param,'align="left"',$sortfield,$sortorder);
1445
+        print_liste_field_titre("Documents2",$url,"name","",$param,'align="left"',$sortfield,$sortorder);
1446
+        print_liste_field_titre("Size",$url,"size","",$param,'align="right"',$sortfield,$sortorder);
1447
+        print_liste_field_titre("Date",$url,"date","",$param,'align="center"',$sortfield,$sortorder);
1448
+        print_liste_field_titre('','','');
1449
+        print '</tr>'."\n";
1450
+
1451
+        // To show ref or specific information according to view to show (defined by $module)
1452
+        if ($modulepart == 'company')
1453
+        {
1454
+            include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1455
+            $object_instance=new Societe($this->db);
1456
+        }
1457
+        else if ($modulepart == 'invoice')
1458
+        {
1459
+            include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1460
+            $object_instance=new Facture($this->db);
1461
+        }
1462
+        else if ($modulepart == 'invoice_supplier')
1463
+        {
1464
+            include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
1465
+            $object_instance=new FactureFournisseur($this->db);
1466
+        }
1467
+        else if ($modulepart == 'propal')
1468
+        {
1469
+            include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
1470
+            $object_instance=new Propal($this->db);
1471
+        }
1472
+        else if ($modulepart == 'supplier_proposal')
1473
+        {
1474
+            include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
1475
+            $object_instance=new SupplierProposal($this->db);
1476
+        }
1477
+        else if ($modulepart == 'order')
1478
+        {
1479
+            include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
1480
+            $object_instance=new Commande($this->db);
1481
+        }
1482
+        else if ($modulepart == 'order_supplier')
1483
+        {
1484
+            include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
1485
+            $object_instance=new CommandeFournisseur($this->db);
1486
+        }
1487
+        else if ($modulepart == 'contract')
1488
+        {
1489
+            include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
1490
+            $object_instance=new Contrat($this->db);
1491
+        }
1492
+        else if ($modulepart == 'product')
1493
+        {
1494
+            include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1495
+            $object_instance=new Product($this->db);
1496
+        }
1497
+        else if ($modulepart == 'tax')
1498
+        {
1499
+            include_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
1500
+            $object_instance=new ChargeSociales($this->db);
1501
+        }
1502
+        else if ($modulepart == 'project')
1503
+        {
1504
+            include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1505
+            $object_instance=new Project($this->db);
1506
+        }
1507
+        else if ($modulepart == 'fichinter')
1508
+        {
1509
+            include_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
1510
+            $object_instance=new Fichinter($this->db);
1511
+        }
1512
+        else if ($modulepart == 'user')
1513
+        {
1514
+            include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1515
+            $object_instance=new User($this->db);
1516
+        }
1517
+        else if ($modulepart == 'expensereport')
1518
+        {
1519
+            include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
1520
+            $object_instance=new ExpenseReport($this->db);
1521
+        }
1522
+        else if ($modulepart == 'holiday')
1523
+        {
1524
+            include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
1525
+            $object_instance=new Holiday($this->db);
1526
+        }
1527
+
1528
+        foreach($filearray as $key => $file)
1529
+        {
1530
+            if (!is_dir($file['name'])
1531
+            && $file['name'] != '.'
1532
+            && $file['name'] != '..'
1533
+            && $file['name'] != 'CVS'
1534
+            && ! preg_match('/\.meta$/i',$file['name']))
1535
+            {
1536
+                // Define relative path used to store the file
1537
+                $relativefile=preg_replace('/'.preg_quote($upload_dir.'/','/').'/','',$file['fullname']);
1538
+
1539
+                //var_dump($file);
1540
+                $id=0; $ref=''; $label='';
1541
+
1542
+                // To show ref or specific information according to view to show (defined by $module)
1543
+                if ($modulepart == 'company')           { preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:''); }
1544
+                if ($modulepart == 'invoice')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1545
+                if ($modulepart == 'invoice_supplier')  { preg_match('/([^\/]+)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:''); if (is_numeric($ref)) { $id=$ref; $ref=''; } }	// $ref may be also id with old supplier invoices
1546
+                if ($modulepart == 'propal')            { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1547
+                if ($modulepart == 'supplier_proposal') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1548
+                if ($modulepart == 'order')             { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1549
+                if ($modulepart == 'order_supplier')    { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1550
+                if ($modulepart == 'contract')          { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1551
+                if ($modulepart == 'product')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:''); }
1552
+                if ($modulepart == 'tax')               { preg_match('/(\d+)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:''); }
1553
+                if ($modulepart == 'project')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:'');}
1554
+                if ($modulepart == 'fichinter')         { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:'');}
1555
+                if ($modulepart == 'user')              { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $id=(isset($reg[1])?$reg[1]:'');}
1556
+                if ($modulepart == 'expensereport')     { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $ref=(isset($reg[1])?$reg[1]:'');}
1557
+                if ($modulepart == 'holiday')           { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg);  $id=(isset($reg[1])?$reg[1]:'');}
1558
+
1559
+                if (! $id && ! $ref) continue;
1560
+                $found=0;
1561
+                if (! empty($this->cache_objects[$modulepart.'_'.$id.'_'.$ref]))
1562
+                {
1563
+                    $found=1;
1564
+                }
1565
+                else
1566
+                {
1567
+                    //print 'Fetch '.$id." - ".$ref.'<br>';
1568
+
1569
+                    if ($id) {
1570
+                        $result = $object_instance->fetch($id);
1571
+                    } else {
1572
+                        //fetchOneLike looks for objects with wildcards in its reference.
1573
+                        //It is useful for those masks who get underscores instead of their actual symbols
1574
+                        //fetchOneLike requires some info in the object. If it doesn't have it, then 0 is returned
1575
+                        //that's why we look only look fetchOneLike when fetch returns 0
1576
+                        if (!$result = $object_instance->fetch('', $ref)) {
1577
+                            $result = $object_instance->fetchOneLike($ref);
1578
+                        }
1579
+                    }
1580
+
1581
+                    if ($result > 0) {  // Save object into a cache
1582
+                        $found=1; $this->cache_objects[$modulepart.'_'.$id.'_'.$ref] = clone $object_instance;
1583
+                    }
1584
+                    if ($result == 0) { $found=1; $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]='notfound'; unset($filearray[$key]); }
1585
+                }
1586
+
1587
+                if (! $found > 0 || ! is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) continue;    // We do not show orphelins files
1588
+
1589
+                print '<!-- Line list_of_autoecmfiles '.$key.' -->'."\n";
1590
+                print '<tr class="oddeven">';
1591
+                print '<td>';
1592
+                if ($found > 0 && is_object($this->cache_objects[$modulepart.'_'.$id.'_'.$ref])) print $this->cache_objects[$modulepart.'_'.$id.'_'.$ref]->getNomUrl(1,'document');
1593
+                else print $langs->trans("ObjectDeleted",($id?$id:$ref));
1594
+
1595
+                //$modulesubdir=dol_sanitizeFileName($ref);
1596
+                $modulesubdir=dirname($relativefile);
1597
+
1598
+                //$filedir=$conf->$modulepart->dir_output . '/' . dol_sanitizeFileName($obj->ref);
1599
+                $filedir=$file['path'];
1600
+                //$urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid;
1601
+                //print $formfile->getDocumentsLink($modulepart, $filename, $filedir);
1602
+
1603
+                print '</td>';
1604
+
1605
+                // File
1606
+                print '<td>';
1607
+                //print "XX".$file['name']; //$file['name'] must be utf8
1608
+                print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1609
+                if ($forcedownload) print '&attachment=1';
1610
+                print '&file='.urlencode($relativefile).'">';
1611
+                print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')');
1612
+                print dol_trunc($file['name'],$maxlength,'middle');
1613
+                print '</a>';
1614
+
1615
+                //print $this->getDocumentsLink($modulepart, $modulesubdir, $filedir, '^'.preg_quote($file['name'],'/').'$');
1616
+                print $this->showPreview($file, $modulepart, $file['relativename']);
1617
+
1618
+                print "</td>\n";
1619
+                print '<td align="right">'.dol_print_size($file['size'],1,1).'</td>';
1620
+                print '<td align="center">'.dol_print_date($file['date'],"dayhour").'</td>';
1621
+                print '<td align="right">';
1622
+                //if (! empty($useinecm))  print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart;
1623
+                //if ($forcedownload) print '&attachment=1';
1624
+                //print '&file='.urlencode($relativefile).'">';
1625
+                //print img_view().'</a> &nbsp; ';
1626
+                //if ($permtodelete) print '<a href="'.$url.'?id='.$object->id.'&section='.$_REQUEST["section"].'&action=delete&urlfile='.urlencode($file['name']).'">'.img_delete().'</a>';
1627
+                //else print '&nbsp;';
1628
+                print "</td></tr>\n";
1629
+            }
1630
+        }
1631
+
1632
+        if (count($filearray) == 0)
1633
+        {
1634
+            print '<tr class="oddeven"><td colspan="5">';
1635
+            if (empty($textifempty)) print $langs->trans("NoFileFound");
1636
+            else print $textifempty;
1637
+            print '</td></tr>';
1638
+        }
1639
+        print "</table>";
1640
+        print '</div>';
1641
+
1642
+        if (! empty($addfilterfields)) print '</form>';
1643
+        // Fin de zone
1644
+    }
1645
+
1646
+    /**
1647
+     *    Show form to upload a new file with jquery fileupload.
1648
+     *    This form use the fileupload.php file.
1649
+     *
1650
+     *    @param	Object	$object		Object to use
1651
+     *    @return	void
1652
+     */
1653
+    private function _formAjaxFileUpload($object)
1654
+    {
1655
+        global $langs, $conf;
1656
+
1657
+        // PHP post_max_size
1658
+        $post_max_size				= ini_get('post_max_size');
1659
+        $mul_post_max_size			= substr($post_max_size, -1);
1660
+        $mul_post_max_size			= ($mul_post_max_size == 'M' ? 1048576 : ($mul_post_max_size == 'K' ? 1024 : ($mul_post_max_size == 'G' ? 1073741824 : 1)));
1661
+        $post_max_size				= $mul_post_max_size * (int) $post_max_size;
1662
+        // PHP upload_max_filesize
1663
+        $upload_max_filesize		= ini_get('upload_max_filesize');
1664
+        $mul_upload_max_filesize	= substr($upload_max_filesize, -1);
1665
+        $mul_upload_max_filesize	= ($mul_upload_max_filesize == 'M' ? 1048576 : ($mul_upload_max_filesize == 'K' ? 1024 : ($mul_upload_max_filesize == 'G' ? 1073741824 : 1)));
1666
+        $upload_max_filesize		= $mul_upload_max_filesize * (int) $upload_max_filesize;
1667
+        // Max file size
1668
+        $max_file_size 				= (($post_max_size < $upload_max_filesize) ? $post_max_size : $upload_max_filesize);
1669
+
1670
+        // Include main
1671
+        include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_main.tpl.php';
1672
+
1673
+        // Include template
1674
+        include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_view.tpl.php';
1675
+    }
1676
+
1677
+    /**
1678
+     * Show array with linked files
1679
+     *
1680
+     * @param 	Object		$object			Object
1681
+     * @param 	int			$permtodelete	Deletion is allowed
1682
+     * @param 	string		$action			Action
1683
+     * @param 	string		$selected		???
1684
+     * @param	string		$param			More param to add into URL
1685
+     * @return 	int							Number of links
1686
+     */
1687
+    public function listOfLinks($object, $permtodelete=1, $action=null, $selected=null, $param='')
1688
+    {
1689
+        global $user, $conf, $langs, $user;
1690
+        global $sortfield, $sortorder;
1691
+
1692
+        $langs->load("link");
1693
+
1694
+        require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
1695
+        $link = new Link($this->db);
1696
+        $links = array();
1697
+        if ($sortfield == "name") {
1698
+            $sortfield = "label";
1699
+        } elseif ($sortfield == "date") {
1700
+            $sortfield = "datea";
1701
+        } else {
1702
+            $sortfield = null;
1703
+        }
1704
+        $res = $link->fetchAll($links, $object->element, $object->id, $sortfield, $sortorder);
1705
+        $param .= (isset($object->id)?'&id=' . $object->id : '');
1706
+
1707
+        // Show list of associated links
1708
+        print load_fiche_titre($langs->trans("LinkedFiles"));
1709
+
1710
+        print '<form action="' . $_SERVER['PHP_SELF'] . ($param?'?'.$param:'') . '" method="POST">';
1711
+
1712
+        print '<table width="100%" class="liste">';
1713
+        print '<tr class="liste_titre">';
1714
+        print_liste_field_titre(
1715
+            $langs->trans("Links"),
1716
+            $_SERVER['PHP_SELF'],
1717
+            "name",
1718
+            "",
1719
+            $param,
1720
+            'align="left"',
1721
+            $sortfield,
1722
+            $sortorder
1723
+        );
1724
+        print_liste_field_titre(
1725
+            "",
1726
+            "",
1727
+            "",
1728
+            "",
1729
+            "",
1730
+            'align="right"'
1731
+        );
1732
+        print_liste_field_titre(
1733
+            $langs->trans("Date"),
1734
+            $_SERVER['PHP_SELF'],
1735
+            "date",
1736
+            "",
1737
+            $param,
1738
+            'align="center"',
1739
+            $sortfield,
1740
+            $sortorder
1741
+        );
1742
+        print_liste_field_titre(
1743
+            '',
1744
+            $_SERVER['PHP_SELF'],
1745
+            "",
1746
+            "",
1747
+            $param,
1748
+            'align="center"'
1749
+        );
1750
+        print_liste_field_titre('','','');
1751
+        print '</tr>';
1752
+        $nboflinks = count($links);
1753
+        if ($nboflinks > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1754
+
1755
+        foreach ($links as $link)
1756
+        {
1757
+            print '<tr class="oddeven">';
1758
+            //edit mode
1759
+            if ($action == 'update' && $selected === $link->id)
1760
+            {
1761
+                print '<td>';
1762
+                print '<input type="hidden" name="id" value="' . $object->id . '">';
1763
+                print '<input type="hidden" name="linkid" value="' . $link->id . '">';
1764
+                print '<input type="hidden" name="action" value="confirm_updateline">';
1765
+                print $langs->trans('Link') . ': <input type="text" name="link" value="' . $link->url . '">';
1766
+                print '</td>';
1767
+                print '<td>';
1768
+                print $langs->trans('Label') . ': <input type="text" name="label" value="' . $link->label . '">';
1769
+                print '</td>';
1770
+                print '<td align="center">' . dol_print_date(dol_now(), "dayhour", "tzuser") . '</td>';
1771
+                print '<td align="right"></td>';
1772
+                print '<td align="right">';
1773
+                print '<input type="submit" name="save" class="button" value="' . dol_escape_htmltag($langs->trans('Save')) . '">';
1774
+                print '<input type="submit" name="cancel" class="button" value="' . dol_escape_htmltag($langs->trans('Cancel')) . '">';
1775
+                print '</td>';
1776
+            }
1777
+            else
1778
+            {
1779
+                print '<td>';
1780
+                print img_picto('', 'object_globe').' ';
1781
+                print '<a data-ajax="false" href="' . $link->url . '" target="_blank">';
1782
+                print $link->label;
1783
+                print '</a>';
1784
+                print '</td>'."\n";
1785
+                print '<td align="right"></td>';
1786
+                print '<td align="center">' . dol_print_date($link->datea, "dayhour", "tzuser") . '</td>';
1787
+                print '<td align="center"></td>';
1788
+                print '<td align="right">';
1789
+                print '<a href="' . $_SERVER['PHP_SELF'] . '?action=update&linkid=' . $link->id . $param . '" class="editfilelink" >' . img_edit() . '</a>';	// id= is included into $param
1790
+                if ($permtodelete) {
1791
+                    print ' &nbsp; <a href="'. $_SERVER['PHP_SELF'] .'?action=delete&linkid=' . $link->id . $param . '" class="deletefilelink">' . img_delete() . '</a>';	// id= is included into $param
1792
+                } else {
1793
+                    print '&nbsp;';
1794
+                }
1795
+                print '</td>';
1796
+            }
1797
+            print "</tr>\n";
1798
+        }
1799
+        if ($nboflinks == 0)
1800
+        {
1801
+            print '<tr class="oddeven"><td colspan="5" class="opacitymedium">';
1802
+            print $langs->trans("NoLinkFound");
1803
+            print '</td></tr>';
1804
+        }
1805
+        print "</table>";
1806
+
1807
+        print '</form>';
1808
+
1809
+        return $nboflinks;
1810
+    }
1811
+
1812
+
1813
+    /**
1814
+     * Show detail icon with link for preview
1815
+     *
1816
+     * @param   array     $file           Array with data of file. Example: array('name'=>...)
1817
+     * @param   string    $modulepart     propal, facture, facture_fourn, ...
1818
+     * @param   string    $relativepath   Relative path of docs
1819
+     * @param   string    $ruleforpicto   Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file)
1820
+     * @param	string	  $param		  More param on http links
1821
+     * @return  string    $out            Output string with HTML
1822
+     */
1823
+    public function showPreview($file, $modulepart, $relativepath, $ruleforpicto=0, $param='')
1824
+    {
1825
+        global $langs, $conf;
1826
+
1827
+        $out='';
1828
+        if ($conf->browser->layout != 'phone' && ! empty($conf->use_javascript_ajax))
1829
+        {
1830
+            $urladvancedpreview=getAdvancedPreviewUrl($modulepart, $relativepath, 1, $param);      // Return if a file is qualified for preview.
1831
+            if (count($urladvancedpreview))
1832
+            {
1833
+                $out.= '<a class="pictopreview '.$urladvancedpreview['css'].'" href="'.$urladvancedpreview['url'].'"'.(empty($urladvancedpreview['mime'])?'':' mime="'.$urladvancedpreview['mime'].'"').' '.(empty($urladvancedpreview['target'])?'':' target="'.$urladvancedpreview['target'].'"').'>';
1834
+                //$out.= '<a class="pictopreview">';
1835
+                if (empty($ruleforpicto))
1836
+                {
1837
+                    //$out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail');
1838
+                    $out.='<span class="fa fa-search-plus" style="color: gray"></span>';
1839
+                }
1840
+                else $out.= img_mime($relativepath, $langs->trans('Preview').' '.$file['name']);
1841
+                $out.= '</a>';
1842
+            }
1843
+        }
1844
+        return $out;
1845
+    }
1846 1846
 }
Please login to merge, or discard this patch.
dolibarr/htdocs/core/class/html.formaccounting.class.php 1 patch
Indentation   +303 added lines, -303 removed lines patch added patch discarded remove patch
@@ -33,110 +33,110 @@  discard block
 block discarded – undo
33 33
 class FormAccounting extends Form
34 34
 {
35 35
 
36
-	private $options_cache = array();
36
+    private $options_cache = array();
37 37
 
38
-	/**
38
+    /**
39 39
      * @var DoliDB Database handler.
40 40
      */
41 41
     public $db;
42 42
 
43
-	/**
44
-	 * @var string Error code (or message)
45
-	 */
46
-	public $error='';
47
-
48
-   /**
49
-	* Constructor
50
-	*
51
-	* @param		DoliDB		$db      Database handler
52
-	*/
53
-	public function __construct($db)
54
-	{
55
-	    $this->db = $db;
56
-	}
43
+    /**
44
+     * @var string Error code (or message)
45
+     */
46
+    public $error='';
47
+
48
+    /**
49
+     * Constructor
50
+     *
51
+     * @param		DoliDB		$db      Database handler
52
+     */
53
+    public function __construct($db)
54
+    {
55
+        $this->db = $db;
56
+    }
57 57
 
58 58
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
59
-	/**
60
-	 * Return list of journals with label by nature
61
-	 *
62
-	 * @param	string	$selectid	Preselected pcg_type
63
-	 * @param	string	$htmlname	Name of field in html form
64
-	 * @param	int		$nature		Limit the list to a particular type of journals (1:various operations / 2:sale / 3:purchase / 4:bank / 9: has-new)
65
-	 * @param	int		$showempty	Add an empty field
66
-	 * @param	int		$select_in	0=selectid value is the journal rowid (default) or 1=selectid is journal code
67
-	 * @param	int		$select_out	Set value returned by select. 0=rowid (default), 1=code
68
-	 * @param	string	$morecss	More css non HTML object
69
-	 * @param	string	$usecache	Key to use to store result into a cache. Next call with same key will reuse the cache.
70
-	 * @param   int     $disabledajaxcombo Disable ajax combo box.
71
-	 * @return	string				String with HTML select
72
-	 */
73
-	function select_journal($selectid, $htmlname = 'journal', $nature=0, $showempty = 0, $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='', $disabledajaxcombo=0)
74
-	{
59
+    /**
60
+     * Return list of journals with label by nature
61
+     *
62
+     * @param	string	$selectid	Preselected pcg_type
63
+     * @param	string	$htmlname	Name of field in html form
64
+     * @param	int		$nature		Limit the list to a particular type of journals (1:various operations / 2:sale / 3:purchase / 4:bank / 9: has-new)
65
+     * @param	int		$showempty	Add an empty field
66
+     * @param	int		$select_in	0=selectid value is the journal rowid (default) or 1=selectid is journal code
67
+     * @param	int		$select_out	Set value returned by select. 0=rowid (default), 1=code
68
+     * @param	string	$morecss	More css non HTML object
69
+     * @param	string	$usecache	Key to use to store result into a cache. Next call with same key will reuse the cache.
70
+     * @param   int     $disabledajaxcombo Disable ajax combo box.
71
+     * @return	string				String with HTML select
72
+     */
73
+    function select_journal($selectid, $htmlname = 'journal', $nature=0, $showempty = 0, $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='', $disabledajaxcombo=0)
74
+    {
75 75
         // phpcs:enable
76
-		global $conf,$langs;
77
-
78
-		$out = '';
79
-
80
-    	$options = array();
81
-		if ($usecache && ! empty($this->options_cache[$usecache]))
82
-		{
83
-		    $options = $this->options_cache[$usecache];
84
-		    $selected=$selectid;
85
-		}
86
-		else
87
-		{
88
-			$sql = "SELECT rowid, code, label, nature, entity, active";
89
-			$sql.= " FROM " . MAIN_DB_PREFIX . "accounting_journal";
90
-			$sql.= " WHERE active = 1";
91
-			$sql.= " AND entity = ".$conf->entity;
92
-			//if ($nature && is_numeric($nature))   $sql .= " AND nature = ".$nature;
93
-			$sql.= " ORDER BY code";
94
-
95
-			dol_syslog(get_class($this) . "::select_journal", LOG_DEBUG);
96
-			$resql = $this->db->query($sql);
97
-
98
-			if (!$resql) {
99
-				$this->error = "Error ".$this->db->lasterror();
100
-				dol_syslog(get_class($this)."::select_journal ".$this->error, LOG_ERR);
101
-				return -1;
102
-			}
103
-
104
-    		$selected = 0;
105
-			$langs->load('accountancy');
106
-			while ($obj = $this->db->fetch_object($resql))
107
-			{
108
-				$label = $obj->code . ' - ' . $langs->trans($obj->label);
109
-
110
-    			$select_value_in = $obj->rowid;
111
-				$select_value_out = $obj->rowid;
112
-
113
-				// Try to guess if we have found default value
114
-    			if ($select_in == 1) {
115
-    				$select_value_in = $obj->code;
116
-    			}
117
-    			if ($select_out == 1) {
118
-    				$select_value_out = $obj->code;
119
-    			}
120
-    			// Remember guy's we store in database llx_accounting_bookkeeping the code of accounting_journal and not the rowid
121
-    			if ($selectid != '' && $selectid == $select_value_in) {
122
-    			    //var_dump("Found ".$selectid." ".$select_value_in);
123
-    				$selected = $select_value_out;
124
-    			}
125
-
126
-				$options[$select_value_out] = $label;
127
-			}
128
-			$this->db->free($resql);
129
-
130
-			if ($usecache)
131
-			{
132
-				$this->options_cache[$usecache] = $options;
133
-			}
134
-		}
135
-
136
-		$out .= Form::selectarray($htmlname, $options, $selected, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, ($disabledajaxcombo?0:1));
137
-
138
-		return $out;
139
-	}
76
+        global $conf,$langs;
77
+
78
+        $out = '';
79
+
80
+        $options = array();
81
+        if ($usecache && ! empty($this->options_cache[$usecache]))
82
+        {
83
+            $options = $this->options_cache[$usecache];
84
+            $selected=$selectid;
85
+        }
86
+        else
87
+        {
88
+            $sql = "SELECT rowid, code, label, nature, entity, active";
89
+            $sql.= " FROM " . MAIN_DB_PREFIX . "accounting_journal";
90
+            $sql.= " WHERE active = 1";
91
+            $sql.= " AND entity = ".$conf->entity;
92
+            //if ($nature && is_numeric($nature))   $sql .= " AND nature = ".$nature;
93
+            $sql.= " ORDER BY code";
94
+
95
+            dol_syslog(get_class($this) . "::select_journal", LOG_DEBUG);
96
+            $resql = $this->db->query($sql);
97
+
98
+            if (!$resql) {
99
+                $this->error = "Error ".$this->db->lasterror();
100
+                dol_syslog(get_class($this)."::select_journal ".$this->error, LOG_ERR);
101
+                return -1;
102
+            }
103
+
104
+            $selected = 0;
105
+            $langs->load('accountancy');
106
+            while ($obj = $this->db->fetch_object($resql))
107
+            {
108
+                $label = $obj->code . ' - ' . $langs->trans($obj->label);
109
+
110
+                $select_value_in = $obj->rowid;
111
+                $select_value_out = $obj->rowid;
112
+
113
+                // Try to guess if we have found default value
114
+                if ($select_in == 1) {
115
+                    $select_value_in = $obj->code;
116
+                }
117
+                if ($select_out == 1) {
118
+                    $select_value_out = $obj->code;
119
+                }
120
+                // Remember guy's we store in database llx_accounting_bookkeeping the code of accounting_journal and not the rowid
121
+                if ($selectid != '' && $selectid == $select_value_in) {
122
+                    //var_dump("Found ".$selectid." ".$select_value_in);
123
+                    $selected = $select_value_out;
124
+                }
125
+
126
+                $options[$select_value_out] = $label;
127
+            }
128
+            $this->db->free($resql);
129
+
130
+            if ($usecache)
131
+            {
132
+                $this->options_cache[$usecache] = $options;
133
+            }
134
+        }
135
+
136
+        $out .= Form::selectarray($htmlname, $options, $selected, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, ($disabledajaxcombo?0:1));
137
+
138
+        return $out;
139
+    }
140 140
 
141 141
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
142 142
     /**
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
             $sql = "SELECT c.rowid, c.label as type, c.range_account";
168 168
             $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
169 169
             $sql.= " WHERE c.active = 1";
170
-			$sql.= " AND c.category_type = 0";
170
+            $sql.= " AND c.category_type = 0";
171 171
             if (empty($allcountries)) $sql.= " AND c.fk_country = ".$mysoc->country_id;
172 172
             $sql.= " ORDER BY c.label ASC";
173 173
         }
@@ -176,8 +176,8 @@  discard block
 block discarded – undo
176 176
             $sql = "SELECT c.rowid, c.label as type, c.range_account";
177 177
             $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c, ".MAIN_DB_PREFIX."c_country as co";
178 178
             $sql.= " WHERE c.active = 1";
179
-			$sql.= " AND c.category_type = 0";
180
-			$sql.= " AND c.fk_country = co.rowid";
179
+            $sql.= " AND c.category_type = 0";
180
+            $sql.= " AND c.fk_country = co.rowid";
181 181
             if (empty($allcountries)) $sql.= " AND co.code = '".$mysoc->country_code."'";
182 182
             $sql.= " ORDER BY c.label ASC";
183 183
         }
@@ -199,7 +199,7 @@  discard block
 block discarded – undo
199 199
                     $out .= '<option value="'.$obj->rowid.'"';
200 200
                     if ($obj->rowid == $selected) $out .= ' selected';
201 201
                     $out .= '>'.($maxlen ? dol_trunc($obj->type,$maxlen) : $obj->type);
202
-					$out .= ' ('.$obj->range_account.')';
202
+                    $out .= ' ('.$obj->range_account.')';
203 203
                     $i++;
204 204
                 }
205 205
                 $out .=  '</select>';
@@ -221,231 +221,231 @@  discard block
 block discarded – undo
221 221
     }
222 222
 
223 223
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
224
-	/**
225
-	 * Return select filter with date of transaction
226
-	 *
227
-	 * @param string $htmlname Name of select field
228
-	 * @param string $selectedkey Value
229
-	 * @return string HTML edit field
230
-	 */
224
+    /**
225
+     * Return select filter with date of transaction
226
+     *
227
+     * @param string $htmlname Name of select field
228
+     * @param string $selectedkey Value
229
+     * @return string HTML edit field
230
+     */
231 231
     function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '')
232 232
     {
233 233
         // phpcs:enable
234
-		$options = array();
234
+        $options = array();
235 235
 
236
-		$sql = 'SELECT DISTINCT import_key from ' . MAIN_DB_PREFIX . 'accounting_bookkeeping';
237
-	    $sql .= " WHERE entity IN (".getEntity('accountancy').")";
238
-		$sql .= ' ORDER BY import_key DESC';
236
+        $sql = 'SELECT DISTINCT import_key from ' . MAIN_DB_PREFIX . 'accounting_bookkeeping';
237
+        $sql .= " WHERE entity IN (".getEntity('accountancy').")";
238
+        $sql .= ' ORDER BY import_key DESC';
239 239
 
240
-		dol_syslog(get_class($this) . "::select_bookkeeping_importkey", LOG_DEBUG);
241
-		$resql = $this->db->query($sql);
240
+        dol_syslog(get_class($this) . "::select_bookkeeping_importkey", LOG_DEBUG);
241
+        $resql = $this->db->query($sql);
242 242
 
243
-		if (!$resql) {
244
-			$this->error = "Error " . $this->db->lasterror();
245
-			dol_syslog(get_class($this) . "::select_bookkeeping_importkey " . $this->error, LOG_ERR);
246
-			return - 1;
247
-		}
243
+        if (!$resql) {
244
+            $this->error = "Error " . $this->db->lasterror();
245
+            dol_syslog(get_class($this) . "::select_bookkeeping_importkey " . $this->error, LOG_ERR);
246
+            return - 1;
247
+        }
248 248
 
249
-		while ($obj = $this->db->fetch_object($resql)) {
250
-			$options[$obj->import_key] = dol_print_date($obj->import_key, 'dayhourtext');
251
-		}
249
+        while ($obj = $this->db->fetch_object($resql)) {
250
+            $options[$obj->import_key] = dol_print_date($obj->import_key, 'dayhourtext');
251
+        }
252 252
 
253
-		return Form::selectarray($htmlname, $options, $selectedkey);
254
-	}
253
+        return Form::selectarray($htmlname, $options, $selectedkey);
254
+    }
255 255
 
256 256
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
257
-	/**
258
-	 * Return list of accounts with label by chart of accounts
259
-	 *
260
-	 * @param string   $selectid           Preselected id or code of accounting accounts (depends on $select_in)
261
-	 * @param string   $htmlname           Name of HTML field id. If name start with '.', it is name of HTML css class, so several component with same name in different forms can be used.
262
-	 * @param int      $showempty          1=Add an empty field, 2=Add an empty field+'None' field
263
-	 * @param array    $event              Event options
264
-	 * @param int      $select_in          0=selectid value is a aa.rowid (default) or 1=selectid is aa.account_number
265
-	 * @param int      $select_out         Set value returned by select. 0=rowid (default), 1=account_number
266
-	 * @param string   $morecss            More css non HTML object
267
-	 * @param string   $usecache           Key to use to store result into a cache. Next call with same key will reuse the cache.
268
-	 * @return string                      String with HTML select
269
-	 */
270
-	function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='')
271
-	{
257
+    /**
258
+     * Return list of accounts with label by chart of accounts
259
+     *
260
+     * @param string   $selectid           Preselected id or code of accounting accounts (depends on $select_in)
261
+     * @param string   $htmlname           Name of HTML field id. If name start with '.', it is name of HTML css class, so several component with same name in different forms can be used.
262
+     * @param int      $showempty          1=Add an empty field, 2=Add an empty field+'None' field
263
+     * @param array    $event              Event options
264
+     * @param int      $select_in          0=selectid value is a aa.rowid (default) or 1=selectid is aa.account_number
265
+     * @param int      $select_out         Set value returned by select. 0=rowid (default), 1=account_number
266
+     * @param string   $morecss            More css non HTML object
267
+     * @param string   $usecache           Key to use to store result into a cache. Next call with same key will reuse the cache.
268
+     * @return string                      String with HTML select
269
+     */
270
+    function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='')
271
+    {
272 272
         // phpcs:enable
273
-		global $conf, $langs;
274
-
275
-		require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
276
-
277
-		$out = '';
278
-
279
-    	$options = array();
280
-		if ($usecache && ! empty($this->options_cache[$usecache]))
281
-		{
282
-		    $options = $this->options_cache[$usecache];
283
-		    $selected=$selectid;
284
-		}
285
-		else
286
-		{
287
-    		$trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT) ? 50 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT;
288
-
289
-    		$sql = "SELECT DISTINCT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version";
290
-    		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
291
-    		$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
292
-    		$sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
293
-    		$sql .= " AND aa.active = 1";
294
-    		$sql .= " AND aa.entity=".$conf->entity;
295
-    		$sql .= " ORDER BY aa.account_number";
296
-
297
-    		dol_syslog(get_class($this) . "::select_account", LOG_DEBUG);
298
-    		$resql = $this->db->query($sql);
299
-
300
-    		if (!$resql) {
301
-    			$this->error = "Error " . $this->db->lasterror();
302
-    			dol_syslog(get_class($this) . "::select_account " . $this->error, LOG_ERR);
303
-    			return -1;
304
-    		}
305
-
306
-    		$selected = 0;
307
-    		while ($obj = $this->db->fetch_object($resql))
308
-    		{
309
-    			$label = length_accountg($obj->account_number) . ' - ' . $obj->label;
310
-    			$label = dol_trunc($label, $trunclength);
311
-
312
-    			$select_value_in = $obj->rowid;
313
-    			$select_value_out = $obj->rowid;
314
-
315
-    			// Try to guess if we have found default value
316
-    			if ($select_in == 1) {
317
-    				$select_value_in = $obj->account_number;
318
-    			}
319
-    			if ($select_out == 1) {
320
-    				$select_value_out = $obj->account_number;
321
-    			}
322
-    			// Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
323
-    			// Because same account_number can be share between different accounting_system and do have the same meaning
324
-    			if ($selectid != '' && $selectid == $select_value_in) {
325
-    			    //var_dump("Found ".$selectid." ".$select_value_in);
326
-    				$selected = $select_value_out;
327
-    			}
328
-
329
-    			$options[$select_value_out] = $label;
330
-    		}
331
-    		$this->db->free($resql);
332
-
333
-    		if ($usecache)
334
-    		{
273
+        global $conf, $langs;
274
+
275
+        require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
276
+
277
+        $out = '';
278
+
279
+        $options = array();
280
+        if ($usecache && ! empty($this->options_cache[$usecache]))
281
+        {
282
+            $options = $this->options_cache[$usecache];
283
+            $selected=$selectid;
284
+        }
285
+        else
286
+        {
287
+            $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT) ? 50 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT;
288
+
289
+            $sql = "SELECT DISTINCT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version";
290
+            $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
291
+            $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
292
+            $sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
293
+            $sql .= " AND aa.active = 1";
294
+            $sql .= " AND aa.entity=".$conf->entity;
295
+            $sql .= " ORDER BY aa.account_number";
296
+
297
+            dol_syslog(get_class($this) . "::select_account", LOG_DEBUG);
298
+            $resql = $this->db->query($sql);
299
+
300
+            if (!$resql) {
301
+                $this->error = "Error " . $this->db->lasterror();
302
+                dol_syslog(get_class($this) . "::select_account " . $this->error, LOG_ERR);
303
+                return -1;
304
+            }
305
+
306
+            $selected = 0;
307
+            while ($obj = $this->db->fetch_object($resql))
308
+            {
309
+                $label = length_accountg($obj->account_number) . ' - ' . $obj->label;
310
+                $label = dol_trunc($label, $trunclength);
311
+
312
+                $select_value_in = $obj->rowid;
313
+                $select_value_out = $obj->rowid;
314
+
315
+                // Try to guess if we have found default value
316
+                if ($select_in == 1) {
317
+                    $select_value_in = $obj->account_number;
318
+                }
319
+                if ($select_out == 1) {
320
+                    $select_value_out = $obj->account_number;
321
+                }
322
+                // Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
323
+                // Because same account_number can be share between different accounting_system and do have the same meaning
324
+                if ($selectid != '' && $selectid == $select_value_in) {
325
+                    //var_dump("Found ".$selectid." ".$select_value_in);
326
+                    $selected = $select_value_out;
327
+                }
328
+
329
+                $options[$select_value_out] = $label;
330
+            }
331
+            $this->db->free($resql);
332
+
333
+            if ($usecache)
334
+            {
335 335
                 $this->options_cache[$usecache] = $options;
336
-    		}
337
-		}
336
+            }
337
+        }
338 338
 
339
-		if ($showempty == 2)
340
-		{
341
-			$options['0'] = $langs->trans("None");
342
-		}
339
+        if ($showempty == 2)
340
+        {
341
+            $options['0'] = $langs->trans("None");
342
+        }
343 343
 
344
-		$out .= Form::selectarray($htmlname, $options, $selected, ($showempty > 0 ? 1 : 0), 0, 0, '', 0, 0, 0, '', $morecss, 1);
344
+        $out .= Form::selectarray($htmlname, $options, $selected, ($showempty > 0 ? 1 : 0), 0, 0, '', 0, 0, 0, '', $morecss, 1);
345 345
 
346
-		return $out;
347
-	}
346
+        return $out;
347
+    }
348 348
 
349 349
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
350
-	/**
351
-	 * Return list of auxilary thirdparty accounts
352
-	 *
353
-	 * @param string   $selectid       Preselected pcg_type
354
-	 * @param string   $htmlname       Name of field in html form
355
-	 * @param int      $showempty      Add an empty field
356
-	 * @param string   $morecss        More css
357
-	 * @return string                  String with HTML select
358
-	 */
350
+    /**
351
+     * Return list of auxilary thirdparty accounts
352
+     *
353
+     * @param string   $selectid       Preselected pcg_type
354
+     * @param string   $htmlname       Name of field in html form
355
+     * @param int      $showempty      Add an empty field
356
+     * @param string   $morecss        More css
357
+     * @return string                  String with HTML select
358
+     */
359 359
     function select_auxaccount($selectid, $htmlname='account_num_aux', $showempty=0, $morecss='maxwidth200')
360 360
     {
361 361
         // phpcs:enable
362 362
 
363
-		$aux_account = array();
364
-
365
-		// Auxiliary customer account
366
-		$sql = "SELECT DISTINCT code_compta, nom ";
367
-		$sql .= " FROM ".MAIN_DB_PREFIX."societe";
368
-	    $sql .= " WHERE entity IN (" . getEntity('societe') . ")";
369
-		$sql .= " ORDER BY code_compta";
370
-		dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
371
-		$resql = $this->db->query($sql);
372
-		if ($resql) {
373
-			while ($obj = $this->db->fetch_object($resql)) {
374
-				if (!empty($obj->code_compta)) {
375
-					$aux_account[$obj->code_compta] = $obj->code_compta.' ('.$obj->nom.')';
376
-				}
377
-			}
378
-		} else {
379
-			$this->error = "Error ".$this->db->lasterror();
380
-			dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
381
-			return -1;
382
-		}
383
-		$this->db->free($resql);
384
-
385
-		// Auxiliary supplier account
386
-		$sql = "SELECT DISTINCT code_compta_fournisseur, nom ";
387
-		$sql .= " FROM ".MAIN_DB_PREFIX."societe";
388
-		$sql .= " WHERE entity IN (" . getEntity('societe') . ")";
389
-		$sql .= " ORDER BY code_compta_fournisseur";
390
-		dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
391
-		$resql = $this->db->query($sql);
392
-		if ($resql) {
393
-			while ($obj = $this->db->fetch_object($resql)) {
394
-				if (!empty($obj->code_compta_fournisseur)) {
395
-					$aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.' ('.$obj->nom.')';
396
-				}
397
-			}
398
-		} else {
399
-			$this->error = "Error ".$this->db->lasterror();
400
-			dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
401
-			return -1;
402
-		}
403
-		$this->db->free($resql);
404
-
405
-		// Build select
406
-		$out .= Form::selectarray($htmlname, $aux_account, $selectid, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
407
-
408
-		return $out;
409
-	}
363
+        $aux_account = array();
364
+
365
+        // Auxiliary customer account
366
+        $sql = "SELECT DISTINCT code_compta, nom ";
367
+        $sql .= " FROM ".MAIN_DB_PREFIX."societe";
368
+        $sql .= " WHERE entity IN (" . getEntity('societe') . ")";
369
+        $sql .= " ORDER BY code_compta";
370
+        dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
371
+        $resql = $this->db->query($sql);
372
+        if ($resql) {
373
+            while ($obj = $this->db->fetch_object($resql)) {
374
+                if (!empty($obj->code_compta)) {
375
+                    $aux_account[$obj->code_compta] = $obj->code_compta.' ('.$obj->nom.')';
376
+                }
377
+            }
378
+        } else {
379
+            $this->error = "Error ".$this->db->lasterror();
380
+            dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
381
+            return -1;
382
+        }
383
+        $this->db->free($resql);
384
+
385
+        // Auxiliary supplier account
386
+        $sql = "SELECT DISTINCT code_compta_fournisseur, nom ";
387
+        $sql .= " FROM ".MAIN_DB_PREFIX."societe";
388
+        $sql .= " WHERE entity IN (" . getEntity('societe') . ")";
389
+        $sql .= " ORDER BY code_compta_fournisseur";
390
+        dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
391
+        $resql = $this->db->query($sql);
392
+        if ($resql) {
393
+            while ($obj = $this->db->fetch_object($resql)) {
394
+                if (!empty($obj->code_compta_fournisseur)) {
395
+                    $aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.' ('.$obj->nom.')';
396
+                }
397
+            }
398
+        } else {
399
+            $this->error = "Error ".$this->db->lasterror();
400
+            dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
401
+            return -1;
402
+        }
403
+        $this->db->free($resql);
404
+
405
+        // Build select
406
+        $out .= Form::selectarray($htmlname, $aux_account, $selectid, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
407
+
408
+        return $out;
409
+    }
410 410
 
411 411
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
412
-	/**
413
-	 * Return HTML combo list of years existing into book keepping
414
-	 *
415
-	 * @param string $selected Preselected value
416
-	 * @param string $htmlname Name of HTML select object
417
-	 * @param int $useempty Affiche valeur vide dans liste
418
-	 * @param string $output_format (html/opton (for option html only)/array (to return options arrays
419
-	 * @return string/array
420
-	 */
421
-	function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
422
-	{
412
+    /**
413
+     * Return HTML combo list of years existing into book keepping
414
+     *
415
+     * @param string $selected Preselected value
416
+     * @param string $htmlname Name of HTML select object
417
+     * @param int $useempty Affiche valeur vide dans liste
418
+     * @param string $output_format (html/opton (for option html only)/array (to return options arrays
419
+     * @return string/array
420
+     */
421
+    function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
422
+    {
423 423
         // phpcs:enable
424
-	    global $conf;
425
-
426
-		$out_array = array();
427
-
428
-		$sql = "SELECT DISTINCT date_format(doc_date,'%Y') as dtyear";
429
-		$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
430
-	    $sql .= " WHERE entity IN (" . getEntity('accountancy') . ")";
431
-		$sql .= " ORDER BY date_format(doc_date,'%Y')";
432
-		dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
433
-		$resql = $this->db->query($sql);
434
-
435
-		if (!$resql) {
436
-			$this->error = "Error ".$this->db->lasterror();
437
-			dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR);
438
-			return -1;
439
-		}
440
-		while ($obj = $this->db->fetch_object($resql)) {
441
-			$out_array[$obj->dtyear] = $obj->dtyear;
442
-		}
443
-		$this->db->free($resql);
444
-
445
-		if ($output_format == 'html') {
446
-			return Form::selectarray($htmlname, $out_array, $selected, $useempty, 0, 0, 'placeholder="aa"');
447
-		} else {
448
-			return $out_array;
449
-		}
450
-	}
424
+        global $conf;
425
+
426
+        $out_array = array();
427
+
428
+        $sql = "SELECT DISTINCT date_format(doc_date,'%Y') as dtyear";
429
+        $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
430
+        $sql .= " WHERE entity IN (" . getEntity('accountancy') . ")";
431
+        $sql .= " ORDER BY date_format(doc_date,'%Y')";
432
+        dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
433
+        $resql = $this->db->query($sql);
434
+
435
+        if (!$resql) {
436
+            $this->error = "Error ".$this->db->lasterror();
437
+            dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR);
438
+            return -1;
439
+        }
440
+        while ($obj = $this->db->fetch_object($resql)) {
441
+            $out_array[$obj->dtyear] = $obj->dtyear;
442
+        }
443
+        $this->db->free($resql);
444
+
445
+        if ($output_format == 'html') {
446
+            return Form::selectarray($htmlname, $out_array, $selected, $useempty, 0, 0, 'placeholder="aa"');
447
+        } else {
448
+            return $out_array;
449
+        }
450
+    }
451 451
 }
Please login to merge, or discard this patch.