Passed
Push — master ( 8f7a8e...7e4a07 )
by Alxarafe
20:11
created
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/commonorder.class.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -37,112 +37,112 @@
 block discarded – undo
37 37
  */
38 38
 abstract class CommonOrderLine extends CommonObjectLine
39 39
 {
40
-	/**
41
-	 * Product ref
42
-	 * @var string
43
-	 * @deprecated Use product_ref
44
-	 * @see product_ref
45
-	 */
46
-	public $ref;
47
-
48
-	/**
49
-	 * Product ref
50
-	 * @var string
51
-	 */
52
-	public $product_ref;
53
-
54
-	/**
55
-	 * Product label
56
-	 * @var string
57
-	 * @deprecated Use product_label
58
-	 * @see product_label
59
-	 */
60
-	public $libelle;
61
-
62
-	/**
63
-	 * Product label
64
-	 * @var string
65
-	 */
66
-	public $product_label;
67
-
68
-	/**
69
-	 * Product description
70
-	 * @var string
71
-	 */
72
-	public $product_desc;
73
-
74
-	/**
75
-	 * Quantity
76
-	 * @var float
77
-	 */
78
-	public $qty;
79
-
80
-	/**
81
-	 * Unit price
82
-	 * @deprecated
83
-	 * @see subprice
84
-	 */
85
-	var $price;
86
-
87
-	/**
88
-	 * Unit price before taxes
89
-	 * @var float
90
-	 */
91
-	public $subprice;
92
-
93
-	/**
94
-	 * Type of the product. 0 for product 1 for service
95
-	 * @var int
96
-	 */
97
-	public $product_type = 0;
98
-
99
-	/**
100
-	 * Description of the line
101
-	 * @var string
102
-	 */
103
-	public $desc;
104
-
105
-	/**
106
-	 * Id of corresponding product
107
-	 * @var int
108
-	 */
109
-	public $fk_product;
110
-
111
-	/**
112
-	 * Percent line discount
113
-	 * @var float
114
-	 */
115
-	public $remise_percent;
116
-
117
-	/**
118
-	 * VAT %
119
-	 * @var float
120
-	 */
121
-	public $tva_tx;
122
-
123
-	/**
124
-	 * Local tax 1 %
125
-	 * @var float
126
-	 */
127
-	public $localtax1_tx;
128
-
129
-	/**
130
-	 * Local tax 2 %
131
-	 * @var float
132
-	 */
133
-	public $localtax2_tx;
134
-
135
-	public $localtax1_type;
136
-	public $localtax2_type;
137
-
138
-	/**
139
-	 * Liste d'options cumulables:
140
-	 * Bit 0:	0 si TVA normal - 1 si TVA NPR
141
-	 * Bit 1:	0 si ligne normal - 1 si bit discount (link to line into llx_remise_except)
142
-	 * @var int
143
-	 */
144
-	public $info_bits = 0;
145
-
146
-	public $special_code = 0;
40
+    /**
41
+     * Product ref
42
+     * @var string
43
+     * @deprecated Use product_ref
44
+     * @see product_ref
45
+     */
46
+    public $ref;
47
+
48
+    /**
49
+     * Product ref
50
+     * @var string
51
+     */
52
+    public $product_ref;
53
+
54
+    /**
55
+     * Product label
56
+     * @var string
57
+     * @deprecated Use product_label
58
+     * @see product_label
59
+     */
60
+    public $libelle;
61
+
62
+    /**
63
+     * Product label
64
+     * @var string
65
+     */
66
+    public $product_label;
67
+
68
+    /**
69
+     * Product description
70
+     * @var string
71
+     */
72
+    public $product_desc;
73
+
74
+    /**
75
+     * Quantity
76
+     * @var float
77
+     */
78
+    public $qty;
79
+
80
+    /**
81
+     * Unit price
82
+     * @deprecated
83
+     * @see subprice
84
+     */
85
+    var $price;
86
+
87
+    /**
88
+     * Unit price before taxes
89
+     * @var float
90
+     */
91
+    public $subprice;
92
+
93
+    /**
94
+     * Type of the product. 0 for product 1 for service
95
+     * @var int
96
+     */
97
+    public $product_type = 0;
98
+
99
+    /**
100
+     * Description of the line
101
+     * @var string
102
+     */
103
+    public $desc;
104
+
105
+    /**
106
+     * Id of corresponding product
107
+     * @var int
108
+     */
109
+    public $fk_product;
110
+
111
+    /**
112
+     * Percent line discount
113
+     * @var float
114
+     */
115
+    public $remise_percent;
116
+
117
+    /**
118
+     * VAT %
119
+     * @var float
120
+     */
121
+    public $tva_tx;
122
+
123
+    /**
124
+     * Local tax 1 %
125
+     * @var float
126
+     */
127
+    public $localtax1_tx;
128
+
129
+    /**
130
+     * Local tax 2 %
131
+     * @var float
132
+     */
133
+    public $localtax2_tx;
134
+
135
+    public $localtax1_type;
136
+    public $localtax2_type;
137
+
138
+    /**
139
+     * Liste d'options cumulables:
140
+     * Bit 0:	0 si TVA normal - 1 si TVA NPR
141
+     * Bit 1:	0 si ligne normal - 1 si bit discount (link to line into llx_remise_except)
142
+     * @var int
143
+     */
144
+    public $info_bits = 0;
145
+
146
+    public $special_code = 0;
147 147
 }
148 148
 
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.formorder.class.php 1 patch
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
 class FormOrder extends Form
32 32
 {
33 33
 
34
-	/**
34
+    /**
35 35
      *    Return combo list of differents status of a orders
36 36
      *
37 37
      *    @param	string	$selected   Preselected value
@@ -41,64 +41,64 @@  discard block
 block discarded – undo
41 41
      */
42 42
     public function selectSupplierOrderStatus($selected='', $short=0, $hmlname='order_status')
43 43
     {
44
-	    $options = array();
45
-
46
-	    // 7 is same label than 6. 8 does not exists (billed is another field)
47
-	    $statustohow = array(
48
-		    '0' => '0',
49
-		    '1' => '1',
50
-		    '2' => '2',
51
-		    '3' => '3',
52
-		    '4' => '4',
53
-		    '5' => '5',
54
-		    '6' => '6,7',
55
-		    '9' => '9'
56
-	    );
57
-
58
-	    $tmpsupplierorder = new CommandeFournisseur($this->db);
59
-
60
-	    foreach ($statustohow as $key => $value) {
61
-		    $tmpsupplierorder->statut = $key;
62
-		    $options[$value] = $tmpsupplierorder->getLibStatut($short);
63
-	    }
64
-
65
-	    print Form::selectarray($hmlname, $options, $selected, 1);
44
+        $options = array();
45
+
46
+        // 7 is same label than 6. 8 does not exists (billed is another field)
47
+        $statustohow = array(
48
+            '0' => '0',
49
+            '1' => '1',
50
+            '2' => '2',
51
+            '3' => '3',
52
+            '4' => '4',
53
+            '5' => '5',
54
+            '6' => '6,7',
55
+            '9' => '9'
56
+        );
57
+
58
+        $tmpsupplierorder = new CommandeFournisseur($this->db);
59
+
60
+        foreach ($statustohow as $key => $value) {
61
+            $tmpsupplierorder->statut = $key;
62
+            $options[$value] = $tmpsupplierorder->getLibStatut($short);
63
+        }
64
+
65
+        print Form::selectarray($hmlname, $options, $selected, 1);
66 66
     }
67 67
 
68
-	/**
69
-	 *	Return list of input method (mode used to receive order, like order received by email, fax, online)
70
-	 *  List found into table c_input_method.
71
-	 *
72
-	 *	@param	string	$selected		Id of preselected input method
73
-	 *  @param  string	$htmlname 		Name of HTML select list
74
-	 *  @param  int		$addempty		0=list with no empty value, 1=list with empty value
75
-	 *  @return	array					Tableau des sources de commandes
76
-	 */
77
-	public function selectInputMethod($selected='',$htmlname='source_id',$addempty=0)
78
-	{
79
-		global $langs;
68
+    /**
69
+     *	Return list of input method (mode used to receive order, like order received by email, fax, online)
70
+     *  List found into table c_input_method.
71
+     *
72
+     *	@param	string	$selected		Id of preselected input method
73
+     *  @param  string	$htmlname 		Name of HTML select list
74
+     *  @param  int		$addempty		0=list with no empty value, 1=list with empty value
75
+     *  @return	array					Tableau des sources de commandes
76
+     */
77
+    public function selectInputMethod($selected='',$htmlname='source_id',$addempty=0)
78
+    {
79
+        global $langs;
80 80
 
81 81
         $listofmethods=array();
82 82
 
83
-		$sql = "SELECT rowid, code, libelle as label";
84
-		$sql.= " FROM ".MAIN_DB_PREFIX."c_input_method";
85
-		$sql.= " WHERE active = 1";
83
+        $sql = "SELECT rowid, code, libelle as label";
84
+        $sql.= " FROM ".MAIN_DB_PREFIX."c_input_method";
85
+        $sql.= " WHERE active = 1";
86 86
 
87
-		dol_syslog(get_class($this)."::selectInputMethod", LOG_DEBUG);
88
-		$resql=$this->db->query($sql);
87
+        dol_syslog(get_class($this)."::selectInputMethod", LOG_DEBUG);
88
+        $resql=$this->db->query($sql);
89 89
 
90
-		if (!$resql) {
91
-			dol_print_error($this->db);
92
-			return -1;
93
-		}
90
+        if (!$resql) {
91
+            dol_print_error($this->db);
92
+            return -1;
93
+        }
94 94
 
95
-		while ($obj = $this->db->fetch_object($resql)) {
96
-			$listofmethods[$obj->rowid] = $langs->trans($obj->code) != $obj->code ? $langs->trans($obj->code) : $obj->label;
97
-		}
95
+        while ($obj = $this->db->fetch_object($resql)) {
96
+            $listofmethods[$obj->rowid] = $langs->trans($obj->code) != $obj->code ? $langs->trans($obj->code) : $obj->label;
97
+        }
98 98
 
99
-		print Form::selectarray($htmlname,$listofmethods,$selected,$addempty);
99
+        print Form::selectarray($htmlname,$listofmethods,$selected,$addempty);
100 100
 
101
-		return 1;
102
-	}
101
+        return 1;
102
+    }
103 103
 }
104 104
 
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/html.formmail.class.php 1 patch
Indentation   +1356 added lines, -1356 removed lines patch added patch discarded remove patch
@@ -36,15 +36,15 @@  discard block
 block discarded – undo
36 36
  */
37 37
 class FormMail extends Form
38 38
 {
39
-	/**
39
+    /**
40 40
      * @var DoliDB Database handler.
41 41
      */
42 42
     public $db;
43 43
 
44
-	public $withform;				// 1=Include HTML form tag and show submit button, 0=Do not include form tag and submit button, -1=Do not include form tag but include submit button
44
+    public $withform;				// 1=Include HTML form tag and show submit button, 0=Do not include form tag and submit button, -1=Do not include form tag but include submit button
45 45
 
46
-	public $fromname;
47
-	public $frommail;
46
+    public $fromname;
47
+    public $frommail;
48 48
 
49 49
     /**
50 50
      * @var string user, company, robot
@@ -67,1391 +67,1391 @@  discard block
 block discarded – undo
67 67
     public $toid;
68 68
 
69 69
     public $replytoname;
70
-	public $replytomail;
71
-	public $toname;
72
-	public $tomail;
73
-	public $trackid;
74
-
75
-	public $withsubstit;			// Show substitution array
76
-	public $withfrom;
77
-
78
-	/**
79
-	 * @var int
80
-	 * @deprecated Fill withto with array before calling method.
81
-	 * @see withto
82
-	 */
83
-	public $withtosocid;
84
-
85
-	/**
86
-	 * @var int|int[]
87
-	 */
88
-	public $withto;				// Show recipient emails
89
-
90
-	public $withtofree;			// Show free text for recipient emails
91
-	public $withtocc;
92
-	public $withtoccc;
93
-	public $withtopic;
94
-	public $withfile;				// 0=No attaches files, 1=Show attached files, 2=Can add new attached files
95
-	public $withmaindocfile;		// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
96
-	public $withbody;
97
-
98
-	public $withfromreadonly;
99
-	public $withreplytoreadonly;
100
-	public $withtoreadonly;
101
-	public $withtoccreadonly;
102
-	public $withtocccreadonly;
103
-	public $withtopicreadonly;
104
-	public $withfilereadonly;
105
-	public $withdeliveryreceipt;
106
-	public $withcancel;
107
-	public $withfckeditor;
108
-
109
-	public $substit=array();
110
-	public $substit_lines=array();
111
-	public $param=array();
112
-
113
-	public $withtouser=array();
114
-	public $withtoccuser=array();
115
-
116
-	public $lines_model;
117
-
118
-
119
-	/**
120
-	 *	Constructor
121
-	 *
122
-	 *  @param	DoliDB	$db      Database handler
123
-	 */
124
-	function __construct($db)
125
-	{
126
-		$this->db = $db;
127
-
128
-		$this->withform=1;
129
-
130
-		$this->withfrom=1;
131
-		$this->withto=1;
132
-		$this->withtofree=1;
133
-		$this->withtocc=1;
134
-		$this->withtoccc=0;
135
-		$this->witherrorsto=0;
136
-		$this->withtopic=1;
137
-		$this->withfile=0;			// 1=Add section "Attached files". 2=Can add files.
138
-		$this->withmaindocfile=0;	// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
139
-		$this->withbody=1;
140
-
141
-		$this->withfromreadonly=1;
142
-		$this->withreplytoreadonly=1;
143
-		$this->withtoreadonly=0;
144
-		$this->withtoccreadonly=0;
145
-		$this->withtocccreadonly=0;
146
-		$this->witherrorstoreadonly=0;
147
-		$this->withtopicreadonly=0;
148
-		$this->withfilereadonly=0;
149
-		$this->withbodyreadonly=0;
150
-		$this->withdeliveryreceiptreadonly=0;
151
-		$this->withfckeditor=-1;	// -1 = Auto
152
-	}
70
+    public $replytomail;
71
+    public $toname;
72
+    public $tomail;
73
+    public $trackid;
74
+
75
+    public $withsubstit;			// Show substitution array
76
+    public $withfrom;
77
+
78
+    /**
79
+     * @var int
80
+     * @deprecated Fill withto with array before calling method.
81
+     * @see withto
82
+     */
83
+    public $withtosocid;
84
+
85
+    /**
86
+     * @var int|int[]
87
+     */
88
+    public $withto;				// Show recipient emails
89
+
90
+    public $withtofree;			// Show free text for recipient emails
91
+    public $withtocc;
92
+    public $withtoccc;
93
+    public $withtopic;
94
+    public $withfile;				// 0=No attaches files, 1=Show attached files, 2=Can add new attached files
95
+    public $withmaindocfile;		// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
96
+    public $withbody;
97
+
98
+    public $withfromreadonly;
99
+    public $withreplytoreadonly;
100
+    public $withtoreadonly;
101
+    public $withtoccreadonly;
102
+    public $withtocccreadonly;
103
+    public $withtopicreadonly;
104
+    public $withfilereadonly;
105
+    public $withdeliveryreceipt;
106
+    public $withcancel;
107
+    public $withfckeditor;
108
+
109
+    public $substit=array();
110
+    public $substit_lines=array();
111
+    public $param=array();
112
+
113
+    public $withtouser=array();
114
+    public $withtoccuser=array();
115
+
116
+    public $lines_model;
117
+
118
+
119
+    /**
120
+     *	Constructor
121
+     *
122
+     *  @param	DoliDB	$db      Database handler
123
+     */
124
+    function __construct($db)
125
+    {
126
+        $this->db = $db;
127
+
128
+        $this->withform=1;
129
+
130
+        $this->withfrom=1;
131
+        $this->withto=1;
132
+        $this->withtofree=1;
133
+        $this->withtocc=1;
134
+        $this->withtoccc=0;
135
+        $this->witherrorsto=0;
136
+        $this->withtopic=1;
137
+        $this->withfile=0;			// 1=Add section "Attached files". 2=Can add files.
138
+        $this->withmaindocfile=0;	// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
139
+        $this->withbody=1;
140
+
141
+        $this->withfromreadonly=1;
142
+        $this->withreplytoreadonly=1;
143
+        $this->withtoreadonly=0;
144
+        $this->withtoccreadonly=0;
145
+        $this->withtocccreadonly=0;
146
+        $this->witherrorstoreadonly=0;
147
+        $this->withtopicreadonly=0;
148
+        $this->withfilereadonly=0;
149
+        $this->withbodyreadonly=0;
150
+        $this->withdeliveryreceiptreadonly=0;
151
+        $this->withfckeditor=-1;	// -1 = Auto
152
+    }
153 153
 
154 154
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
155
-	/**
156
-	 * Clear list of attached files in send mail form (also stored in session)
157
-	 *
158
-	 * @return	void
159
-	 */
160
-	function clear_attached_files()
161
-	{
155
+    /**
156
+     * Clear list of attached files in send mail form (also stored in session)
157
+     *
158
+     * @return	void
159
+     */
160
+    function clear_attached_files()
161
+    {
162 162
         // phpcs:enable
163
-		global $conf,$user;
164
-		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
163
+        global $conf,$user;
164
+        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
165 165
 
166
-		// Set tmp user directory
167
-		$vardir=$conf->user->dir_output."/".$user->id;
168
-		$upload_dir = $vardir.'/temp/';                     // TODO Add $keytoavoidconflict in upload_dir path
169
-		if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir);
166
+        // Set tmp user directory
167
+        $vardir=$conf->user->dir_output."/".$user->id;
168
+        $upload_dir = $vardir.'/temp/';                     // TODO Add $keytoavoidconflict in upload_dir path
169
+        if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir);
170 170
 
171
-		$keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
172
-		unset($_SESSION["listofpaths".$keytoavoidconflict]);
173
-		unset($_SESSION["listofnames".$keytoavoidconflict]);
174
-		unset($_SESSION["listofmimes".$keytoavoidconflict]);
175
-	}
171
+        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
172
+        unset($_SESSION["listofpaths".$keytoavoidconflict]);
173
+        unset($_SESSION["listofnames".$keytoavoidconflict]);
174
+        unset($_SESSION["listofmimes".$keytoavoidconflict]);
175
+    }
176 176
 
177 177
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
178
-	/**
179
-	 * Add a file into the list of attached files (stored in SECTION array)
180
-	 *
181
-	 * @param 	string   $path   Full absolute path on filesystem of file, including file name
182
-	 * @param 	string   $file   Only filename (can be basename($path))
183
-	 * @param 	string   $type   Mime type (can be dol_mimetype($file))
184
-	 * @return	void
185
-	 */
186
-	function add_attached_files($path, $file='', $type='')
187
-	{
178
+    /**
179
+     * Add a file into the list of attached files (stored in SECTION array)
180
+     *
181
+     * @param 	string   $path   Full absolute path on filesystem of file, including file name
182
+     * @param 	string   $file   Only filename (can be basename($path))
183
+     * @param 	string   $type   Mime type (can be dol_mimetype($file))
184
+     * @return	void
185
+     */
186
+    function add_attached_files($path, $file='', $type='')
187
+    {
188 188
         // phpcs:enable
189
-		$listofpaths=array();
190
-		$listofnames=array();
191
-		$listofmimes=array();
192
-
193
-		if (empty($file)) $file=basename($path);
194
-		if (empty($type)) $type=dol_mimetype($file);
195
-
196
-		$keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
197
-		if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
198
-		if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
199
-		if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
200
-		if (! in_array($file,$listofnames))
201
-		{
202
-			$listofpaths[]=$path;
203
-			$listofnames[]=$file;
204
-			$listofmimes[]=$type;
205
-			$_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
206
-			$_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
207
-			$_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
208
-		}
209
-	}
189
+        $listofpaths=array();
190
+        $listofnames=array();
191
+        $listofmimes=array();
192
+
193
+        if (empty($file)) $file=basename($path);
194
+        if (empty($type)) $type=dol_mimetype($file);
195
+
196
+        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
197
+        if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
198
+        if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
199
+        if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
200
+        if (! in_array($file,$listofnames))
201
+        {
202
+            $listofpaths[]=$path;
203
+            $listofnames[]=$file;
204
+            $listofmimes[]=$type;
205
+            $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
206
+            $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
207
+            $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
208
+        }
209
+    }
210 210
 
211 211
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
212
-	/**
213
-	 * Remove a file from the list of attached files (stored in SECTION array)
214
-	 *
215
-	 * @param  	string	$keytodelete     Key in file array (0, 1, 2, ...)
216
-	 * @return	void
217
-	 */
218
-	function remove_attached_files($keytodelete)
219
-	{
212
+    /**
213
+     * Remove a file from the list of attached files (stored in SECTION array)
214
+     *
215
+     * @param  	string	$keytodelete     Key in file array (0, 1, 2, ...)
216
+     * @return	void
217
+     */
218
+    function remove_attached_files($keytodelete)
219
+    {
220 220
         // phpcs:enable
221
-		$listofpaths=array();
222
-		$listofnames=array();
223
-		$listofmimes=array();
224
-
225
-		$keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
226
-		if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
227
-		if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
228
-		if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
229
-		if ($keytodelete >= 0)
230
-		{
231
-			unset ($listofpaths[$keytodelete]);
232
-			unset ($listofnames[$keytodelete]);
233
-			unset ($listofmimes[$keytodelete]);
234
-			$_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
235
-			$_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
236
-			$_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
237
-			//var_dump($_SESSION['listofpaths']);
238
-		}
239
-	}
221
+        $listofpaths=array();
222
+        $listofnames=array();
223
+        $listofmimes=array();
224
+
225
+        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
226
+        if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
227
+        if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
228
+        if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
229
+        if ($keytodelete >= 0)
230
+        {
231
+            unset ($listofpaths[$keytodelete]);
232
+            unset ($listofnames[$keytodelete]);
233
+            unset ($listofmimes[$keytodelete]);
234
+            $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
235
+            $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
236
+            $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
237
+            //var_dump($_SESSION['listofpaths']);
238
+        }
239
+    }
240 240
 
241 241
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
242
-	/**
243
-	 * Return list of attached files (stored in SECTION array)
244
-	 *
245
-	 * @return	array       array('paths'=> ,'names'=>, 'mimes'=> )
246
-	 */
247
-	function get_attached_files()
248
-	{
242
+    /**
243
+     * Return list of attached files (stored in SECTION array)
244
+     *
245
+     * @return	array       array('paths'=> ,'names'=>, 'mimes'=> )
246
+     */
247
+    function get_attached_files()
248
+    {
249 249
         // phpcs:enable
250
-		$listofpaths=array();
251
-		$listofnames=array();
252
-		$listofmimes=array();
250
+        $listofpaths=array();
251
+        $listofnames=array();
252
+        $listofmimes=array();
253 253
 
254
-		$keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
255
-		if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
256
-		if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
257
-		if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
258
-		return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
259
-	}
254
+        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
255
+        if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
256
+        if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
257
+        if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
258
+        return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
259
+    }
260 260
 
261 261
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
262
-	/**
263
-	 *	Show the form to input an email
264
-	 *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
265
-	 *  this->withmaindocfile
266
-	 *
267
-	 *	@param	string	$addfileaction		Name of action when posting file attachments
268
-	 *	@param	string	$removefileaction	Name of action when removing file attachments
269
-	 *	@return	void
270
-	 */
271
-	function show_form($addfileaction='addfile',$removefileaction='removefile')
272
-	{
262
+    /**
263
+     *	Show the form to input an email
264
+     *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
265
+     *  this->withmaindocfile
266
+     *
267
+     *	@param	string	$addfileaction		Name of action when posting file attachments
268
+     *	@param	string	$removefileaction	Name of action when removing file attachments
269
+     *	@return	void
270
+     */
271
+    function show_form($addfileaction='addfile',$removefileaction='removefile')
272
+    {
273 273
         // phpcs:enable
274
-		print $this->get_form($addfileaction,$removefileaction);
275
-	}
274
+        print $this->get_form($addfileaction,$removefileaction);
275
+    }
276 276
 
277 277
     // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
278
-	/**
279
-	 *	Get the form to input an email
280
-	 *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
281
-	 *  this->withfile
282
-	 *  this->param:	Contains more parameters like email templates info
283
-	 *
284
-	 *	@param	string	$addfileaction		Name of action when posting file attachments
285
-	 *	@param	string	$removefileaction	Name of action when removing file attachments
286
-	 *	@return string						Form to show
287
-	 */
288
-	function get_form($addfileaction='addfile', $removefileaction='removefile')
289
-	{
278
+    /**
279
+     *	Get the form to input an email
280
+     *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
281
+     *  this->withfile
282
+     *  this->param:	Contains more parameters like email templates info
283
+     *
284
+     *	@param	string	$addfileaction		Name of action when posting file attachments
285
+     *	@param	string	$removefileaction	Name of action when removing file attachments
286
+     *	@return string						Form to show
287
+     */
288
+    function get_form($addfileaction='addfile', $removefileaction='removefile')
289
+    {
290 290
         // phpcs:enable
291
-		global $conf, $langs, $user, $hookmanager, $form;
291
+        global $conf, $langs, $user, $hookmanager, $form;
292 292
 
293
-		if (! is_object($form)) $form=new Form($this->db);
293
+        if (! is_object($form)) $form=new Form($this->db);
294 294
 
295
-		// Load translation files required by the page
295
+        // Load translation files required by the page
296 296
         $langs->loadLangs(array('other', 'mails'));
297 297
 
298
-		// Clear temp files. Must be done at beginning, before call of triggers
299
-		if (GETPOST('mode','alpha') == 'init' || (GETPOST('modelmailselected','alpha') && GETPOST('modelmailselected','alpha') != '-1'))
300
-		{
301
-			$this->clear_attached_files();
302
-		}
303
-
304
-		// Call hook getFormMail
305
-		$hookmanager->initHooks(array('formmail'));
306
-
307
-		$parameters=array(
308
-			'addfileaction' => $addfileaction,
309
-			'removefileaction'=> $removefileaction,
310
-			'trackid'=> $this->trackid
311
-		);
312
-		$reshook=$hookmanager->executeHooks('getFormMail', $parameters, $this);
313
-
314
-		if (!empty($reshook))
315
-		{
316
-			return $hookmanager->resPrint;
317
-		}
318
-		else
319
-		{
320
-			$out='';
321
-
322
-			$disablebademails=1;
323
-
324
-			// Define output language
325
-			$outputlangs = $langs;
326
-			$newlang = '';
327
-			if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $this->param['langsmodels'];
328
-			if (! empty($newlang))
329
-			{
330
-				$outputlangs = new Translate("", $conf);
331
-				$outputlangs->setDefaultLang($newlang);
332
-				$outputlangs->load('other');
333
-			}
334
-
335
-			// Get message template for $this->param["models"] into c_email_templates
336
-			$arraydefaultmessage = -1;
337
-			if ($this->param['models'] != 'none')
338
-			{
339
-				$model_id=0;
340
-				if (array_key_exists('models_id',$this->param))
341
-				{
342
-					$model_id=$this->param["models_id"];
343
-				}
344
-
345
-				$arraydefaultmessage=$this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);		// If $model_id is empty, preselect the first one
346
-			}
347
-
348
-			// Define list of attached files
349
-			$listofpaths=array();
350
-			$listofnames=array();
351
-			$listofmimes=array();
352
-			$keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
353
-
354
-			if (GETPOST('mode','alpha') == 'init' || (GETPOST('modelmailselected','alpha') && GETPOST('modelmailselected','alpha') != '-1'))
355
-			{
356
-				if (! empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit']))
357
-				{
358
-					foreach($this->param['fileinit'] as $file)
359
-					{
360
-						$this->add_attached_files($file, basename($file), dol_mimetype($file));
361
-					}
362
-				}
363
-			}
364
-
365
-	   		if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
366
-	   		if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
367
-	   		if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
368
-
369
-
370
-			$out.= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
371
-			if ($this->withform == 1)
372
-			{
373
-				$out.= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
374
-
375
-				$out.= '<a id="formmail" name="formmail"></a>';
376
-				$out.= '<input style="display:none" type="submit" id="sendmail" name="sendmail">';
377
-				$out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
378
-				$out.= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
379
-			}
380
-			if (! empty($this->withfrom))
381
-			{
382
-				if (! empty($this->withfromreadonly))
383
-				{
384
-					$out.= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
385
-					$out.= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
386
-				}
387
-			}
388
-			foreach ($this->param as $key=>$value)
389
-			{
390
-				$out.= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
391
-			}
392
-
393
-			$modelmail_array=array();
394
-			if ($this->param['models'] != 'none')
395
-			{
396
-				$result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
397
-				if ($result < 0)
398
-				{
399
-					setEventMessages($this->error, $this->errors, 'errors');
400
-				}
401
-				foreach($this->lines_model as $line)
402
-				{
403
-					$langs->trans("members");
404
-					if (preg_match('/\((.*)\)/', $line->label, $reg))
405
-					{
406
-						$modelmail_array[$line->id]=$langs->trans($reg[1]);		// langs->trans when label is __(xxx)__
407
-					}
408
-					else
409
-					{
410
-						$modelmail_array[$line->id]=$line->label;
411
-					}
412
-					if ($line->lang) $modelmail_array[$line->id].=' ('.$line->lang.')';
413
-					if ($line->private) $modelmail_array[$line->id].=' - '.$langs->trans("Private");
414
-					//if ($line->fk_user != $user->id) $modelmail_array[$line->id].=' - '.$langs->trans("By").' ';
415
-				}
416
-			}
417
-
418
-			// Zone to select email template
419
-			if (count($modelmail_array)>0)
420
-			{
421
-				// If list of template is filled
422
-				$out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
423
-				$out.= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> '.$this->selectarray('modelmailselected', $modelmail_array, 0, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100');
424
-				if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
425
-				$out.= ' &nbsp; ';
426
-				$out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
427
-				$out.= ' &nbsp; ';
428
-				$out.= '</div>';
429
-			}
430
-			elseif (! empty($this->param['models']) && in_array($this->param['models'], array(
431
-					'propal_send','order_send','facture_send',
432
-					'shipping_send','fichinter_send','supplier_proposal_send','order_supplier_send',
433
-					'invoice_supplier_send','thirdparty','contract','user','all'
434
-		   		)))
435
-			{
436
-				// If list of template is empty
437
-				$out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
438
-				$out.= $langs->trans('SelectMailModel').': <select name="modelmailselected" disabled="disabled"><option value="none">'.$langs->trans("NoTemplateDefined").'</option></select>';    // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy.
439
-				if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
440
-				$out.= ' &nbsp; ';
441
-				$out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
442
-				$out.= ' &nbsp; ';
443
-				$out.= '</div>';
444
-			}
445
-
446
-
447
-
448
-			$out.= '<table class="tableforemailform boxtablenotop" width="100%">'."\n";
449
-
450
-			// Substitution array/string
451
-			$helpforsubstitution='';
452
-			if (is_array($this->substit) && count($this->substit)) $helpforsubstitution.=$langs->trans('AvailableVariables').' :<br>'."\n";
453
-			foreach($this->substit as $key => $val)
454
-			{
455
-				$helpforsubstitution.=$key.' -> '.$langs->trans(dol_string_nohtmltag($val)).'<br>';
456
-			}
457
-			if (! empty($this->withsubstit))		// Unset or set ->withsubstit=0 to disable this.
458
-			{
459
-				$out.= '<tr><td colspan="2" align="right">';
460
-				//$out.='<div class="floatright">';
461
-				if (is_numeric($this->withsubstit)) $out.= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip');	// Old usage
462
-				else $out.= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip');															// New usage
463
-				$out.= "</td></tr>\n";
464
-				//$out.='</div>';
465
-			}
466
-
467
-			/*var_dump(! empty($this->withfromreadonly));
298
+        // Clear temp files. Must be done at beginning, before call of triggers
299
+        if (GETPOST('mode','alpha') == 'init' || (GETPOST('modelmailselected','alpha') && GETPOST('modelmailselected','alpha') != '-1'))
300
+        {
301
+            $this->clear_attached_files();
302
+        }
303
+
304
+        // Call hook getFormMail
305
+        $hookmanager->initHooks(array('formmail'));
306
+
307
+        $parameters=array(
308
+            'addfileaction' => $addfileaction,
309
+            'removefileaction'=> $removefileaction,
310
+            'trackid'=> $this->trackid
311
+        );
312
+        $reshook=$hookmanager->executeHooks('getFormMail', $parameters, $this);
313
+
314
+        if (!empty($reshook))
315
+        {
316
+            return $hookmanager->resPrint;
317
+        }
318
+        else
319
+        {
320
+            $out='';
321
+
322
+            $disablebademails=1;
323
+
324
+            // Define output language
325
+            $outputlangs = $langs;
326
+            $newlang = '';
327
+            if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $this->param['langsmodels'];
328
+            if (! empty($newlang))
329
+            {
330
+                $outputlangs = new Translate("", $conf);
331
+                $outputlangs->setDefaultLang($newlang);
332
+                $outputlangs->load('other');
333
+            }
334
+
335
+            // Get message template for $this->param["models"] into c_email_templates
336
+            $arraydefaultmessage = -1;
337
+            if ($this->param['models'] != 'none')
338
+            {
339
+                $model_id=0;
340
+                if (array_key_exists('models_id',$this->param))
341
+                {
342
+                    $model_id=$this->param["models_id"];
343
+                }
344
+
345
+                $arraydefaultmessage=$this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);		// If $model_id is empty, preselect the first one
346
+            }
347
+
348
+            // Define list of attached files
349
+            $listofpaths=array();
350
+            $listofnames=array();
351
+            $listofmimes=array();
352
+            $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
353
+
354
+            if (GETPOST('mode','alpha') == 'init' || (GETPOST('modelmailselected','alpha') && GETPOST('modelmailselected','alpha') != '-1'))
355
+            {
356
+                if (! empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit']))
357
+                {
358
+                    foreach($this->param['fileinit'] as $file)
359
+                    {
360
+                        $this->add_attached_files($file, basename($file), dol_mimetype($file));
361
+                    }
362
+                }
363
+            }
364
+
365
+                if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
366
+                if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
367
+                if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
368
+
369
+
370
+            $out.= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
371
+            if ($this->withform == 1)
372
+            {
373
+                $out.= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
374
+
375
+                $out.= '<a id="formmail" name="formmail"></a>';
376
+                $out.= '<input style="display:none" type="submit" id="sendmail" name="sendmail">';
377
+                $out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
378
+                $out.= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
379
+            }
380
+            if (! empty($this->withfrom))
381
+            {
382
+                if (! empty($this->withfromreadonly))
383
+                {
384
+                    $out.= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
385
+                    $out.= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
386
+                }
387
+            }
388
+            foreach ($this->param as $key=>$value)
389
+            {
390
+                $out.= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
391
+            }
392
+
393
+            $modelmail_array=array();
394
+            if ($this->param['models'] != 'none')
395
+            {
396
+                $result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
397
+                if ($result < 0)
398
+                {
399
+                    setEventMessages($this->error, $this->errors, 'errors');
400
+                }
401
+                foreach($this->lines_model as $line)
402
+                {
403
+                    $langs->trans("members");
404
+                    if (preg_match('/\((.*)\)/', $line->label, $reg))
405
+                    {
406
+                        $modelmail_array[$line->id]=$langs->trans($reg[1]);		// langs->trans when label is __(xxx)__
407
+                    }
408
+                    else
409
+                    {
410
+                        $modelmail_array[$line->id]=$line->label;
411
+                    }
412
+                    if ($line->lang) $modelmail_array[$line->id].=' ('.$line->lang.')';
413
+                    if ($line->private) $modelmail_array[$line->id].=' - '.$langs->trans("Private");
414
+                    //if ($line->fk_user != $user->id) $modelmail_array[$line->id].=' - '.$langs->trans("By").' ';
415
+                }
416
+            }
417
+
418
+            // Zone to select email template
419
+            if (count($modelmail_array)>0)
420
+            {
421
+                // If list of template is filled
422
+                $out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
423
+                $out.= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> '.$this->selectarray('modelmailselected', $modelmail_array, 0, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100');
424
+                if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
425
+                $out.= ' &nbsp; ';
426
+                $out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
427
+                $out.= ' &nbsp; ';
428
+                $out.= '</div>';
429
+            }
430
+            elseif (! empty($this->param['models']) && in_array($this->param['models'], array(
431
+                    'propal_send','order_send','facture_send',
432
+                    'shipping_send','fichinter_send','supplier_proposal_send','order_supplier_send',
433
+                    'invoice_supplier_send','thirdparty','contract','user','all'
434
+                    )))
435
+            {
436
+                // If list of template is empty
437
+                $out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
438
+                $out.= $langs->trans('SelectMailModel').': <select name="modelmailselected" disabled="disabled"><option value="none">'.$langs->trans("NoTemplateDefined").'</option></select>';    // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy.
439
+                if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
440
+                $out.= ' &nbsp; ';
441
+                $out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
442
+                $out.= ' &nbsp; ';
443
+                $out.= '</div>';
444
+            }
445
+
446
+
447
+
448
+            $out.= '<table class="tableforemailform boxtablenotop" width="100%">'."\n";
449
+
450
+            // Substitution array/string
451
+            $helpforsubstitution='';
452
+            if (is_array($this->substit) && count($this->substit)) $helpforsubstitution.=$langs->trans('AvailableVariables').' :<br>'."\n";
453
+            foreach($this->substit as $key => $val)
454
+            {
455
+                $helpforsubstitution.=$key.' -> '.$langs->trans(dol_string_nohtmltag($val)).'<br>';
456
+            }
457
+            if (! empty($this->withsubstit))		// Unset or set ->withsubstit=0 to disable this.
458
+            {
459
+                $out.= '<tr><td colspan="2" align="right">';
460
+                //$out.='<div class="floatright">';
461
+                if (is_numeric($this->withsubstit)) $out.= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip');	// Old usage
462
+                else $out.= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip');															// New usage
463
+                $out.= "</td></tr>\n";
464
+                //$out.='</div>';
465
+            }
466
+
467
+            /*var_dump(! empty($this->withfromreadonly));
468 468
 			var_dump($this->withfrom);
469 469
 			var_dump($this->fromtype);
470 470
 			var_dump($this->fromname);*/
471 471
 
472
-			// From
473
-			if (! empty($this->withfrom))
474
-			{
475
-				if (! empty($this->withfromreadonly))
476
-				{
477
-					$out.= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
478
-
479
-					// $this->fromtype is the default value to use to select sender
480
-					if (! ($this->fromtype === 'user' && $this->fromid > 0)
481
-						&& ! ($this->fromtype === 'company')
482
-						&& ! ($this->fromtype === 'robot')
483
-						&& ! preg_match('/user_aliases/', $this->fromtype)
484
-						&& ! preg_match('/global_aliases/', $this->fromtype)
485
-						&& ! preg_match('/senderprofile/', $this->fromtype)
486
-						)
487
-					{
488
-						// Use this->fromname and this->frommail or error if not defined
489
-						$out.= $this->fromname;
490
-						if ($this->frommail)
491
-						{
492
-							$out.= ' &lt;'.$this->frommail.'&gt;';
493
-						}
494
-						else
495
-						{
496
-							if ($this->fromtype)
497
-							{
498
-								$langs->load('errors');
499
-								$out.= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
500
-							}
501
-						}
502
-					} else {
503
-						$liste = array();
504
-
505
-						// Add user email
506
-						if (empty($user->email))
507
-						{
508
-							$langs->load('errors');
509
-							$liste['user'] = $user->getFullName($langs) . ' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
510
-						}
511
-						else
512
-						{
513
-							$liste['user'] = $user->getFullName($langs) .' &lt;'.$user->email.'&gt;';
514
-						}
515
-
516
-						// Add also company main email
517
-						$liste['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM .' &lt;'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'&gt;';
518
-
519
-						// Add also email aliases if there is some
520
-						$listaliases=array('user_aliases'=>$user->email_aliases, 'global_aliases'=>$conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
521
-
522
-						// Also add robot email
523
-						if (! empty($this->fromalsorobot))
524
-						{
525
-							if (! empty($conf->global->MAIN_MAIL_EMAIL_FROM) && $conf->global->MAIN_MAIL_EMAIL_FROM != $conf->global->MAIN_INFO_SOCIETE_MAIL)
526
-							{
527
-								$liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM;
528
-								if ($this->frommail)
529
-								{
530
-									$liste['robot'] .= ' &lt;'.$conf->global->MAIN_MAIL_EMAIL_FROM.'&gt;';
531
-								}
532
-							}
533
-						}
534
-
535
-						// Add also email aliases from the c_email_senderprofile table
536
-						$sql='SELECT rowid, label, email FROM '.MAIN_DB_PREFIX.'c_email_senderprofile WHERE active = 1 ORDER BY position';
537
-						$resql = $this->db->query($sql);
538
-						if ($resql)
539
-						{
540
-							$num = $this->db->num_rows($resql);
541
-							$i=0;
542
-							while($i < $num)
543
-							{
544
-								$obj = $this->db->fetch_object($resql);
545
-								if ($obj)
546
-								{
547
-									$listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
548
-								}
549
-								$i++;
550
-							}
551
-						}
552
-						else dol_print_error($this->db);
553
-
554
-						foreach($listaliases as $typealias => $listalias)
555
-						{
556
-							$posalias=0;
557
-							$listaliasarray=explode(',', $listalias);
558
-							foreach ($listaliasarray as $listaliasval)
559
-							{
560
-								$posalias++;
561
-								$listaliasval=trim($listaliasval);
562
-								if ($listaliasval)
563
-								{
564
-									$listaliasval=preg_replace('/</', '&lt;', $listaliasval);
565
-									$listaliasval=preg_replace('/>/', '&gt;', $listaliasval);
566
-									if (! preg_match('/&lt;/', $listaliasval)) $listaliasval='&lt;'.$listaliasval.'&gt;';
567
-									$liste[$typealias.'_'.$posalias]=$listaliasval;
568
-								}
569
-							}
570
-						}
571
-
572
-						// Set the default "From"
573
-						$defaultfrom='';
574
-						$reshook=$hookmanager->executeHooks('getDefaultFromEmail', $parameters, $this);
575
-						if (empty($reshook))
576
-						{
577
-							$defaultfrom = $this->fromtype;
578
-						}
579
-						if (! empty($hookmanager->resArray['defaultfrom'])) $defaultfrom=$hookmanager->resArray['defaultfrom'];
580
-
581
-						// Using combo here make the '<email>' no more visible on list.
582
-						//$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
583
-						$out.= ' '.$form->selectarray('fromtype', $liste, $defaultfrom, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 0, '', $disablebademails);
584
-					}
585
-
586
-					$out.= "</td></tr>\n";
587
-				}
588
-				else
589
-				{
590
-					$out.= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
591
-					$out.= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
592
-					$out.= '&nbsp; &nbsp; ';
593
-					$out.= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
594
-					$out.= "</td></tr>\n";
595
-				}
596
-			}
597
-
598
-			// To
599
-			if (! empty($this->withto) || is_array($this->withto))
600
-			{
601
-				$out.= '<tr><td class="fieldrequired">';
602
-				if ($this->withtofree) $out.= $form->textwithpicto($langs->trans("MailTo"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
603
-				else $out.= $langs->trans("MailTo");
604
-				$out.= '</td><td>';
605
-				if ($this->withtoreadonly)
606
-				{
607
-					if (! empty($this->toname) && ! empty($this->tomail))
608
-					{
609
-						$out.= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
610
-						$out.= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
611
-						if ($this->totype == 'thirdparty')
612
-						{
613
-							$soc=new Societe($this->db);
614
-							$soc->fetch($this->toid);
615
-							$out.= $soc->getNomUrl(1);
616
-						}
617
-						else if ($this->totype == 'contact')
618
-						{
619
-							$contact=new Contact($this->db);
620
-							$contact->fetch($this->toid);
621
-							$out.= $contact->getNomUrl(1);
622
-						}
623
-						else
624
-						{
625
-							$out.= $this->toname;
626
-						}
627
-						$out.= ' &lt;'.$this->tomail.'&gt;';
628
-						if ($this->withtofree)
629
-						{
630
-							$out.= '<br>'.$langs->trans("and").' <input class="minwidth200" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
631
-						}
632
-					}
633
-					else
634
-					{
635
-						// Note withto may be a text like 'AllRecipientSelected'
636
-						$out.= (! is_array($this->withto) && ! is_numeric($this->withto))?$this->withto:"";
637
-					}
638
-				}
639
-				else
640
-				{
641
-					if (! empty($this->withtofree))
642
-					{
643
-						$out.= '<input class="minwidth200" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
644
-					}
645
-					if (! empty($this->withto) && is_array($this->withto))
646
-					{
647
-						if (! empty($this->withtofree)) $out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
648
-						// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
649
-						$tmparray = $this->withto;
650
-						foreach($tmparray as $key => $val)
651
-						{
652
-							$tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
653
-						}
654
-						$withtoselected=GETPOST("receiver",'none');     // Array of selected value
655
-						if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
656
-						{
657
-							$withtoselected = array_keys($tmparray);
658
-						}
659
-						$out.= $form->multiselectarray("receiver", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
660
-					}
661
-				}
662
-				$out.= "</td></tr>\n";
663
-			}
664
-
665
-			// To User
666
-			if (! empty($this->withtouser) && is_array($this->withtouser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT))
667
-			{
668
-				$out.= '<tr><td>';
669
-				$out.= $langs->trans("MailToUsers");
670
-				$out.= '</td><td>';
671
-
672
-				// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
673
-				$tmparray = $this->withtouser;
674
-				foreach($tmparray as $key => $val)
675
-				{
676
-					$tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
677
-				}
678
-				$withtoselected=GETPOST("receiveruser",'none');     // Array of selected value
679
-				if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
680
-				{
681
-					$withtoselected = array_keys($tmparray);
682
-				}
683
-				$out.= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
684
-				$out.= "</td></tr>\n";
685
-			}
686
-
687
-			// withoptiononeemailperrecipient
688
-			if (! empty($this->withoptiononeemailperrecipient))
689
-			{
690
-				$out.= '<tr><td class="minwidth200">';
691
-				$out.= $langs->trans("GroupEmails");
692
-				$out.= '</td><td>';
693
-				$out.=' <input type="checkbox" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0?' checked="checked"':'').'> ';
694
-				$out.= $langs->trans("OneEmailPerRecipient");
695
-				$out.='<span class="hideonsmartphone">';
696
-				$out.=' - ';
697
-				$out.= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
698
-				$out.='</span>';
699
-				$out.= '</td></tr>';
700
-			}
701
-
702
-			// CC
703
-			if (! empty($this->withtocc) || is_array($this->withtocc))
704
-			{
705
-				$out.= '<tr><td>';
706
-				$out.= $form->textwithpicto($langs->trans("MailCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
707
-				$out.= '</td><td>';
708
-				if ($this->withtoccreadonly)
709
-				{
710
-					$out.= (! is_array($this->withtocc) && ! is_numeric($this->withtocc))?$this->withtocc:"";
711
-				}
712
-				else
713
-				{
714
-					$out.= '<input class="minwidth200" id="sendtocc" name="sendtocc" value="'.((! is_array($this->withtocc) && ! is_numeric($this->withtocc))? (isset($_POST["sendtocc"])?$_POST["sendtocc"]:$this->withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />';
715
-					if (! empty($this->withtocc) && is_array($this->withtocc))
716
-					{
717
-						$out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
718
-						// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
719
-						$tmparray = $this->withtocc;
720
-						foreach($tmparray as $key => $val)
721
-						{
722
-							$tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
723
-						}
724
-						$withtoccselected=GETPOST("receivercc");     // Array of selected value
725
-						$out.= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, null, null, 'inline-block minwidth500',null, "");
726
-					}
727
-				}
728
-				$out.= "</td></tr>\n";
729
-			}
730
-
731
-			// To User cc
732
-			if (! empty($this->withtoccuser) && is_array($this->withtoccuser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT))
733
-			{
734
-				$out.= '<tr><td>';
735
-				$out.= $langs->trans("MailToCCUsers");
736
-				$out.= '</td><td>';
737
-
738
-				// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
739
-				$tmparray = $this->withtoccuser;
740
-				foreach($tmparray as $key => $val)
741
-				{
742
-					$tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
743
-				}
744
-				$withtoselected=GETPOST("receiverccuser",'none');     // Array of selected value
745
-				if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
746
-				{
747
-					$withtoselected = array_keys($tmparray);
748
-				}
749
-				$out.= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
750
-				$out.= "</td></tr>\n";
751
-			}
752
-
753
-			// CCC
754
-			if (! empty($this->withtoccc) || is_array($this->withtoccc)) {
755
-				$out .= $this->getHtmlForWithCcc();
756
-			}
757
-
758
-			// Replyto
759
-			if (! empty($this->withreplyto))
760
-			{
761
-				if ($this->withreplytoreadonly)
762
-				{
763
-					$out.= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
764
-					$out.= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
765
-					$out.= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail?(" &lt;".$this->replytomail."&gt;"):"");
766
-					$out.= "</td></tr>\n";
767
-				}
768
-			}
769
-
770
-			// Errorsto
771
-			if (! empty($this->witherrorsto)) {
772
-				$out .= $this->getHtmlForWithErrorsTo();
773
-			}
774
-
775
-			// Ask delivery receipt
776
-			if (! empty($this->withdeliveryreceipt)) {
777
-				$out .= $this->getHtmlForDeliveryReceipt();
778
-			}
779
-
780
-			// Topic
781
-			if (! empty($this->withtopic)) {
782
-				$out .= $this->getHtmlForTopic();
783
-			}
784
-
785
-			// Attached files
786
-			if (! empty($this->withfile))
787
-			{
788
-				$out.= '<tr>';
789
-				$out.= '<td>'.$langs->trans("MailFile").'</td>';
790
-
791
-				$out.= '<td>';
792
-
793
-				if ($this->withmaindocfile)	// withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
794
-				{
795
-					if (GETPOSTISSET('sendmail'))
796
-					{
797
-						$this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
798
-					}
799
-					// If a template was selected, we use setup of template to define if join file checkbox is selected or not.
800
-					elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0)
801
-					{
802
-						$this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
803
-					}
804
-				}
805
-
806
-				if (! empty($this->withmaindocfile))
807
-				{
808
-					if ($this->withmaindocfile == 1)
809
-					{
810
-						$out.='<input type="checkbox" name="addmaindocfile" value="1" />';
811
-					}
812
-					if ($this->withmaindocfile == -1)
813
-					{
814
-						$out.='<input type="checkbox" name="addmaindocfile" value="1" checked="checked" />';
815
-					}
816
-					$out.=' '.$langs->trans("JoinMainDoc").'.<br>';
817
-				}
818
-
819
-				if (is_numeric($this->withfile))
820
-				{
821
-					// TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
822
-					$out.= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
823
-					$out.= '<script type="text/javascript" language="javascript">';
824
-					$out.= 'jQuery(document).ready(function () {';
825
-					$out.= '    jQuery(".removedfile").click(function() {';
826
-					$out.= '        jQuery(".removedfilehidden").val(jQuery(this).val());';
827
-					$out.= '    });';
828
-					$out.= '})';
829
-					$out.= '</script>'."\n";
830
-					if (count($listofpaths))
831
-					{
832
-						foreach($listofpaths as $key => $val)
833
-						{
834
-							$out.= '<div id="attachfile_'.$key.'">';
835
-							$out.= img_mime($listofnames[$key]).' '.$listofnames[$key];
836
-							if (! $this->withfilereadonly)
837
-							{
838
-								$out.= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key+1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
839
-								//$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
840
-							}
841
-							$out.= '<br></div>';
842
-						}
843
-					}
844
-					else if (empty($this->withmaindocfile))		// Do not show message if we asked to show the checkbox
845
-					{
846
-						$out.= $langs->trans("NoAttachedFiles").'<br>';
847
-					}
848
-					if ($this->withfile == 2)	// Can add other files
849
-					{
850
-						if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) $out.= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
851
-						else $out.= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
852
-						$out.= ' ';
853
-						$out.= '<input class="button" type="submit" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
854
-					}
855
-				}
856
-				else
857
-				{
858
-					$out.=$this->withfile;
859
-				}
860
-
861
-				$out.= "</td></tr>\n";
862
-			}
863
-
864
-			// Message
865
-			if (! empty($this->withbody))
866
-			{
867
-				$defaultmessage=GETPOST('message','none');
868
-				if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1')
869
-				{
870
-					if ($arraydefaultmessage && $arraydefaultmessage->content) {
871
-						$defaultmessage = $arraydefaultmessage->content;
872
-					} elseif (! is_numeric($this->withbody)) {
873
-						$defaultmessage = $this->withbody;
874
-					}
875
-				}
876
-
877
-				// Complete substitution array with the url to make online payment
878
-				$paymenturl=''; $validpaymentmethod=array();
879
-				if (empty($this->substit['__REF__']))
880
-				{
881
-					$paymenturl='';
882
-				}
883
-				else
884
-				{
885
-					// Set the online payment url link into __ONLINE_PAYMENT_URL__ key
886
-					require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
887
-					$langs->loadLangs(array('paypal','other'));
888
-					$typeforonlinepayment='free';
889
-					if ($this->param["models"]=='order'   || $this->param["models"]=='order_send')   $typeforonlinepayment='order';		// TODO use detection on something else than template
890
-					if ($this->param["models"]=='invoice' || $this->param["models"]=='facture_send') $typeforonlinepayment='invoice';	// TODO use detection on something else than template
891
-					if ($this->param["models"]=='member') $typeforonlinepayment='member';												// TODO use detection on something else than template
892
-					$url=getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
893
-					$paymenturl=$url;
894
-
895
-					$validpaymentmethod = getValidOnlinePaymentMethods('');
896
-				}
897
-
898
-				if (count($validpaymentmethod) > 0 && $paymenturl)
899
-				{
900
-					$langs->load('other');
901
-					$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']=str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
902
-					$this->substit['__ONLINE_PAYMENT_URL__']=$paymenturl;
903
-				}
904
-				else
905
-				{
906
-					$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']='';
907
-					$this->substit['__ONLINE_PAYMENT_URL__']='';
908
-				}
909
-
910
-				//Add lines substitution key from each line
911
-				$lines = '';
912
-				$defaultlines = $arraydefaultmessage->content_lines;
913
-				if (isset($defaultlines))
914
-				{
915
-					foreach ($this->substit_lines as $substit_line)
916
-					{
917
-						$lines .= make_substitutions($defaultlines,$substit_line)."\n";
918
-					}
919
-				}
920
-				$this->substit['__LINES__']=$lines;
921
-
922
-				$defaultmessage=str_replace('\n',"\n",$defaultmessage);
923
-
924
-				// Deal with format differences between message and signature (text / HTML)
925
-				if (dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
926
-					$this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
927
-				} else if(!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
928
-					$defaultmessage = dol_nl2br($defaultmessage);
929
-				}
930
-
931
-				if (isset($_POST["message"]) && ! $_POST['modelselected']) $defaultmessage=$_POST["message"];
932
-				else
933
-				{
934
-					$defaultmessage=make_substitutions($defaultmessage,$this->substit);
935
-					// Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
936
-					$defaultmessage=preg_replace("/^(<br>)+/","",$defaultmessage);
937
-					$defaultmessage=preg_replace("/^\n+/","",$defaultmessage);
938
-				}
939
-
940
-				$out.= '<tr>';
941
-				$out.= '<td valign="top">';
942
-				$out.=$form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
943
-				$out.='</td>';
944
-				$out.= '<td>';
945
-				if ($this->withbodyreadonly)
946
-				{
947
-					$out.= nl2br($defaultmessage);
948
-					$out.= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
949
-				}
950
-				else
951
-				{
952
-					if (! isset($this->ckeditortoolbar)) $this->ckeditortoolbar = 'dolibarr_notes';
953
-
954
-					// Editor wysiwyg
955
-					require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
956
-					if ($this->withfckeditor == -1)
957
-					{
958
-						if (! empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor=1;
959
-						else $this->withfckeditor=0;
960
-					}
961
-
962
-					$doleditor=new DolEditor('message',$defaultmessage,'',280,$this->ckeditortoolbar,'In',true,true,$this->withfckeditor,8,'95%');
963
-					$out.= $doleditor->Create(1);
964
-				}
965
-				$out.= "</td></tr>\n";
966
-			}
967
-
968
-			$out.= '</table>'."\n";
969
-
970
-			if ($this->withform == 1 || $this->withform == -1)
971
-			{
972
-				$out.= '<br><div class="center">';
973
-				$out.= '<input class="button" type="submit" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
974
-				// Add a javascript test to avoid to forget to submit file before sending email
975
-				if ($this->withfile == 2 && $conf->use_javascript_ajax)
976
-				{
977
-					$out.= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
978
-				}
979
-				$out.= ' />';
980
-				if ($this->withcancel)
981
-				{
982
-					$out.= ' &nbsp; &nbsp; ';
983
-					$out.= '<input class="button" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
984
-				}
985
-				$out.= '</div>'."\n";
986
-			}
987
-
988
-			if ($this->withform == 1) $out.= '</form>'."\n";
989
-
990
-			// Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
991
-			if (! empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY))
992
-			{
993
-				$out.= '<script type="text/javascript" language="javascript">';
994
-				$out.= 'jQuery(document).ready(function () {';
995
-				$out.= '	$(document).on("keypress", \'#mailform\', function (e) {		/* Note this is called at every key pressed ! */
472
+            // From
473
+            if (! empty($this->withfrom))
474
+            {
475
+                if (! empty($this->withfromreadonly))
476
+                {
477
+                    $out.= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
478
+
479
+                    // $this->fromtype is the default value to use to select sender
480
+                    if (! ($this->fromtype === 'user' && $this->fromid > 0)
481
+                        && ! ($this->fromtype === 'company')
482
+                        && ! ($this->fromtype === 'robot')
483
+                        && ! preg_match('/user_aliases/', $this->fromtype)
484
+                        && ! preg_match('/global_aliases/', $this->fromtype)
485
+                        && ! preg_match('/senderprofile/', $this->fromtype)
486
+                        )
487
+                    {
488
+                        // Use this->fromname and this->frommail or error if not defined
489
+                        $out.= $this->fromname;
490
+                        if ($this->frommail)
491
+                        {
492
+                            $out.= ' &lt;'.$this->frommail.'&gt;';
493
+                        }
494
+                        else
495
+                        {
496
+                            if ($this->fromtype)
497
+                            {
498
+                                $langs->load('errors');
499
+                                $out.= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
500
+                            }
501
+                        }
502
+                    } else {
503
+                        $liste = array();
504
+
505
+                        // Add user email
506
+                        if (empty($user->email))
507
+                        {
508
+                            $langs->load('errors');
509
+                            $liste['user'] = $user->getFullName($langs) . ' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
510
+                        }
511
+                        else
512
+                        {
513
+                            $liste['user'] = $user->getFullName($langs) .' &lt;'.$user->email.'&gt;';
514
+                        }
515
+
516
+                        // Add also company main email
517
+                        $liste['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM .' &lt;'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'&gt;';
518
+
519
+                        // Add also email aliases if there is some
520
+                        $listaliases=array('user_aliases'=>$user->email_aliases, 'global_aliases'=>$conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
521
+
522
+                        // Also add robot email
523
+                        if (! empty($this->fromalsorobot))
524
+                        {
525
+                            if (! empty($conf->global->MAIN_MAIL_EMAIL_FROM) && $conf->global->MAIN_MAIL_EMAIL_FROM != $conf->global->MAIN_INFO_SOCIETE_MAIL)
526
+                            {
527
+                                $liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM;
528
+                                if ($this->frommail)
529
+                                {
530
+                                    $liste['robot'] .= ' &lt;'.$conf->global->MAIN_MAIL_EMAIL_FROM.'&gt;';
531
+                                }
532
+                            }
533
+                        }
534
+
535
+                        // Add also email aliases from the c_email_senderprofile table
536
+                        $sql='SELECT rowid, label, email FROM '.MAIN_DB_PREFIX.'c_email_senderprofile WHERE active = 1 ORDER BY position';
537
+                        $resql = $this->db->query($sql);
538
+                        if ($resql)
539
+                        {
540
+                            $num = $this->db->num_rows($resql);
541
+                            $i=0;
542
+                            while($i < $num)
543
+                            {
544
+                                $obj = $this->db->fetch_object($resql);
545
+                                if ($obj)
546
+                                {
547
+                                    $listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
548
+                                }
549
+                                $i++;
550
+                            }
551
+                        }
552
+                        else dol_print_error($this->db);
553
+
554
+                        foreach($listaliases as $typealias => $listalias)
555
+                        {
556
+                            $posalias=0;
557
+                            $listaliasarray=explode(',', $listalias);
558
+                            foreach ($listaliasarray as $listaliasval)
559
+                            {
560
+                                $posalias++;
561
+                                $listaliasval=trim($listaliasval);
562
+                                if ($listaliasval)
563
+                                {
564
+                                    $listaliasval=preg_replace('/</', '&lt;', $listaliasval);
565
+                                    $listaliasval=preg_replace('/>/', '&gt;', $listaliasval);
566
+                                    if (! preg_match('/&lt;/', $listaliasval)) $listaliasval='&lt;'.$listaliasval.'&gt;';
567
+                                    $liste[$typealias.'_'.$posalias]=$listaliasval;
568
+                                }
569
+                            }
570
+                        }
571
+
572
+                        // Set the default "From"
573
+                        $defaultfrom='';
574
+                        $reshook=$hookmanager->executeHooks('getDefaultFromEmail', $parameters, $this);
575
+                        if (empty($reshook))
576
+                        {
577
+                            $defaultfrom = $this->fromtype;
578
+                        }
579
+                        if (! empty($hookmanager->resArray['defaultfrom'])) $defaultfrom=$hookmanager->resArray['defaultfrom'];
580
+
581
+                        // Using combo here make the '<email>' no more visible on list.
582
+                        //$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
583
+                        $out.= ' '.$form->selectarray('fromtype', $liste, $defaultfrom, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 0, '', $disablebademails);
584
+                    }
585
+
586
+                    $out.= "</td></tr>\n";
587
+                }
588
+                else
589
+                {
590
+                    $out.= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
591
+                    $out.= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
592
+                    $out.= '&nbsp; &nbsp; ';
593
+                    $out.= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
594
+                    $out.= "</td></tr>\n";
595
+                }
596
+            }
597
+
598
+            // To
599
+            if (! empty($this->withto) || is_array($this->withto))
600
+            {
601
+                $out.= '<tr><td class="fieldrequired">';
602
+                if ($this->withtofree) $out.= $form->textwithpicto($langs->trans("MailTo"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
603
+                else $out.= $langs->trans("MailTo");
604
+                $out.= '</td><td>';
605
+                if ($this->withtoreadonly)
606
+                {
607
+                    if (! empty($this->toname) && ! empty($this->tomail))
608
+                    {
609
+                        $out.= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
610
+                        $out.= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
611
+                        if ($this->totype == 'thirdparty')
612
+                        {
613
+                            $soc=new Societe($this->db);
614
+                            $soc->fetch($this->toid);
615
+                            $out.= $soc->getNomUrl(1);
616
+                        }
617
+                        else if ($this->totype == 'contact')
618
+                        {
619
+                            $contact=new Contact($this->db);
620
+                            $contact->fetch($this->toid);
621
+                            $out.= $contact->getNomUrl(1);
622
+                        }
623
+                        else
624
+                        {
625
+                            $out.= $this->toname;
626
+                        }
627
+                        $out.= ' &lt;'.$this->tomail.'&gt;';
628
+                        if ($this->withtofree)
629
+                        {
630
+                            $out.= '<br>'.$langs->trans("and").' <input class="minwidth200" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
631
+                        }
632
+                    }
633
+                    else
634
+                    {
635
+                        // Note withto may be a text like 'AllRecipientSelected'
636
+                        $out.= (! is_array($this->withto) && ! is_numeric($this->withto))?$this->withto:"";
637
+                    }
638
+                }
639
+                else
640
+                {
641
+                    if (! empty($this->withtofree))
642
+                    {
643
+                        $out.= '<input class="minwidth200" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
644
+                    }
645
+                    if (! empty($this->withto) && is_array($this->withto))
646
+                    {
647
+                        if (! empty($this->withtofree)) $out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
648
+                        // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
649
+                        $tmparray = $this->withto;
650
+                        foreach($tmparray as $key => $val)
651
+                        {
652
+                            $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
653
+                        }
654
+                        $withtoselected=GETPOST("receiver",'none');     // Array of selected value
655
+                        if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
656
+                        {
657
+                            $withtoselected = array_keys($tmparray);
658
+                        }
659
+                        $out.= $form->multiselectarray("receiver", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
660
+                    }
661
+                }
662
+                $out.= "</td></tr>\n";
663
+            }
664
+
665
+            // To User
666
+            if (! empty($this->withtouser) && is_array($this->withtouser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT))
667
+            {
668
+                $out.= '<tr><td>';
669
+                $out.= $langs->trans("MailToUsers");
670
+                $out.= '</td><td>';
671
+
672
+                // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
673
+                $tmparray = $this->withtouser;
674
+                foreach($tmparray as $key => $val)
675
+                {
676
+                    $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
677
+                }
678
+                $withtoselected=GETPOST("receiveruser",'none');     // Array of selected value
679
+                if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
680
+                {
681
+                    $withtoselected = array_keys($tmparray);
682
+                }
683
+                $out.= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
684
+                $out.= "</td></tr>\n";
685
+            }
686
+
687
+            // withoptiononeemailperrecipient
688
+            if (! empty($this->withoptiononeemailperrecipient))
689
+            {
690
+                $out.= '<tr><td class="minwidth200">';
691
+                $out.= $langs->trans("GroupEmails");
692
+                $out.= '</td><td>';
693
+                $out.=' <input type="checkbox" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0?' checked="checked"':'').'> ';
694
+                $out.= $langs->trans("OneEmailPerRecipient");
695
+                $out.='<span class="hideonsmartphone">';
696
+                $out.=' - ';
697
+                $out.= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
698
+                $out.='</span>';
699
+                $out.= '</td></tr>';
700
+            }
701
+
702
+            // CC
703
+            if (! empty($this->withtocc) || is_array($this->withtocc))
704
+            {
705
+                $out.= '<tr><td>';
706
+                $out.= $form->textwithpicto($langs->trans("MailCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
707
+                $out.= '</td><td>';
708
+                if ($this->withtoccreadonly)
709
+                {
710
+                    $out.= (! is_array($this->withtocc) && ! is_numeric($this->withtocc))?$this->withtocc:"";
711
+                }
712
+                else
713
+                {
714
+                    $out.= '<input class="minwidth200" id="sendtocc" name="sendtocc" value="'.((! is_array($this->withtocc) && ! is_numeric($this->withtocc))? (isset($_POST["sendtocc"])?$_POST["sendtocc"]:$this->withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />';
715
+                    if (! empty($this->withtocc) && is_array($this->withtocc))
716
+                    {
717
+                        $out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
718
+                        // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
719
+                        $tmparray = $this->withtocc;
720
+                        foreach($tmparray as $key => $val)
721
+                        {
722
+                            $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
723
+                        }
724
+                        $withtoccselected=GETPOST("receivercc");     // Array of selected value
725
+                        $out.= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, null, null, 'inline-block minwidth500',null, "");
726
+                    }
727
+                }
728
+                $out.= "</td></tr>\n";
729
+            }
730
+
731
+            // To User cc
732
+            if (! empty($this->withtoccuser) && is_array($this->withtoccuser) && !empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT))
733
+            {
734
+                $out.= '<tr><td>';
735
+                $out.= $langs->trans("MailToCCUsers");
736
+                $out.= '</td><td>';
737
+
738
+                // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
739
+                $tmparray = $this->withtoccuser;
740
+                foreach($tmparray as $key => $val)
741
+                {
742
+                    $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
743
+                }
744
+                $withtoselected=GETPOST("receiverccuser",'none');     // Array of selected value
745
+                if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
746
+                {
747
+                    $withtoselected = array_keys($tmparray);
748
+                }
749
+                $out.= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
750
+                $out.= "</td></tr>\n";
751
+            }
752
+
753
+            // CCC
754
+            if (! empty($this->withtoccc) || is_array($this->withtoccc)) {
755
+                $out .= $this->getHtmlForWithCcc();
756
+            }
757
+
758
+            // Replyto
759
+            if (! empty($this->withreplyto))
760
+            {
761
+                if ($this->withreplytoreadonly)
762
+                {
763
+                    $out.= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
764
+                    $out.= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
765
+                    $out.= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail?(" &lt;".$this->replytomail."&gt;"):"");
766
+                    $out.= "</td></tr>\n";
767
+                }
768
+            }
769
+
770
+            // Errorsto
771
+            if (! empty($this->witherrorsto)) {
772
+                $out .= $this->getHtmlForWithErrorsTo();
773
+            }
774
+
775
+            // Ask delivery receipt
776
+            if (! empty($this->withdeliveryreceipt)) {
777
+                $out .= $this->getHtmlForDeliveryReceipt();
778
+            }
779
+
780
+            // Topic
781
+            if (! empty($this->withtopic)) {
782
+                $out .= $this->getHtmlForTopic();
783
+            }
784
+
785
+            // Attached files
786
+            if (! empty($this->withfile))
787
+            {
788
+                $out.= '<tr>';
789
+                $out.= '<td>'.$langs->trans("MailFile").'</td>';
790
+
791
+                $out.= '<td>';
792
+
793
+                if ($this->withmaindocfile)	// withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
794
+                {
795
+                    if (GETPOSTISSET('sendmail'))
796
+                    {
797
+                        $this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
798
+                    }
799
+                    // If a template was selected, we use setup of template to define if join file checkbox is selected or not.
800
+                    elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0)
801
+                    {
802
+                        $this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
803
+                    }
804
+                }
805
+
806
+                if (! empty($this->withmaindocfile))
807
+                {
808
+                    if ($this->withmaindocfile == 1)
809
+                    {
810
+                        $out.='<input type="checkbox" name="addmaindocfile" value="1" />';
811
+                    }
812
+                    if ($this->withmaindocfile == -1)
813
+                    {
814
+                        $out.='<input type="checkbox" name="addmaindocfile" value="1" checked="checked" />';
815
+                    }
816
+                    $out.=' '.$langs->trans("JoinMainDoc").'.<br>';
817
+                }
818
+
819
+                if (is_numeric($this->withfile))
820
+                {
821
+                    // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
822
+                    $out.= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
823
+                    $out.= '<script type="text/javascript" language="javascript">';
824
+                    $out.= 'jQuery(document).ready(function () {';
825
+                    $out.= '    jQuery(".removedfile").click(function() {';
826
+                    $out.= '        jQuery(".removedfilehidden").val(jQuery(this).val());';
827
+                    $out.= '    });';
828
+                    $out.= '})';
829
+                    $out.= '</script>'."\n";
830
+                    if (count($listofpaths))
831
+                    {
832
+                        foreach($listofpaths as $key => $val)
833
+                        {
834
+                            $out.= '<div id="attachfile_'.$key.'">';
835
+                            $out.= img_mime($listofnames[$key]).' '.$listofnames[$key];
836
+                            if (! $this->withfilereadonly)
837
+                            {
838
+                                $out.= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key+1).'" class="removedfile" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
839
+                                //$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
840
+                            }
841
+                            $out.= '<br></div>';
842
+                        }
843
+                    }
844
+                    else if (empty($this->withmaindocfile))		// Do not show message if we asked to show the checkbox
845
+                    {
846
+                        $out.= $langs->trans("NoAttachedFiles").'<br>';
847
+                    }
848
+                    if ($this->withfile == 2)	// Can add other files
849
+                    {
850
+                        if (!empty($conf->global->FROM_MAIL_USE_INPUT_FILE_MULTIPLE)) $out.= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
851
+                        else $out.= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
852
+                        $out.= ' ';
853
+                        $out.= '<input class="button" type="submit" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
854
+                    }
855
+                }
856
+                else
857
+                {
858
+                    $out.=$this->withfile;
859
+                }
860
+
861
+                $out.= "</td></tr>\n";
862
+            }
863
+
864
+            // Message
865
+            if (! empty($this->withbody))
866
+            {
867
+                $defaultmessage=GETPOST('message','none');
868
+                if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1')
869
+                {
870
+                    if ($arraydefaultmessage && $arraydefaultmessage->content) {
871
+                        $defaultmessage = $arraydefaultmessage->content;
872
+                    } elseif (! is_numeric($this->withbody)) {
873
+                        $defaultmessage = $this->withbody;
874
+                    }
875
+                }
876
+
877
+                // Complete substitution array with the url to make online payment
878
+                $paymenturl=''; $validpaymentmethod=array();
879
+                if (empty($this->substit['__REF__']))
880
+                {
881
+                    $paymenturl='';
882
+                }
883
+                else
884
+                {
885
+                    // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
886
+                    require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
887
+                    $langs->loadLangs(array('paypal','other'));
888
+                    $typeforonlinepayment='free';
889
+                    if ($this->param["models"]=='order'   || $this->param["models"]=='order_send')   $typeforonlinepayment='order';		// TODO use detection on something else than template
890
+                    if ($this->param["models"]=='invoice' || $this->param["models"]=='facture_send') $typeforonlinepayment='invoice';	// TODO use detection on something else than template
891
+                    if ($this->param["models"]=='member') $typeforonlinepayment='member';												// TODO use detection on something else than template
892
+                    $url=getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
893
+                    $paymenturl=$url;
894
+
895
+                    $validpaymentmethod = getValidOnlinePaymentMethods('');
896
+                }
897
+
898
+                if (count($validpaymentmethod) > 0 && $paymenturl)
899
+                {
900
+                    $langs->load('other');
901
+                    $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']=str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
902
+                    $this->substit['__ONLINE_PAYMENT_URL__']=$paymenturl;
903
+                }
904
+                else
905
+                {
906
+                    $this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']='';
907
+                    $this->substit['__ONLINE_PAYMENT_URL__']='';
908
+                }
909
+
910
+                //Add lines substitution key from each line
911
+                $lines = '';
912
+                $defaultlines = $arraydefaultmessage->content_lines;
913
+                if (isset($defaultlines))
914
+                {
915
+                    foreach ($this->substit_lines as $substit_line)
916
+                    {
917
+                        $lines .= make_substitutions($defaultlines,$substit_line)."\n";
918
+                    }
919
+                }
920
+                $this->substit['__LINES__']=$lines;
921
+
922
+                $defaultmessage=str_replace('\n',"\n",$defaultmessage);
923
+
924
+                // Deal with format differences between message and signature (text / HTML)
925
+                if (dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
926
+                    $this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
927
+                } else if(!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
928
+                    $defaultmessage = dol_nl2br($defaultmessage);
929
+                }
930
+
931
+                if (isset($_POST["message"]) && ! $_POST['modelselected']) $defaultmessage=$_POST["message"];
932
+                else
933
+                {
934
+                    $defaultmessage=make_substitutions($defaultmessage,$this->substit);
935
+                    // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
936
+                    $defaultmessage=preg_replace("/^(<br>)+/","",$defaultmessage);
937
+                    $defaultmessage=preg_replace("/^\n+/","",$defaultmessage);
938
+                }
939
+
940
+                $out.= '<tr>';
941
+                $out.= '<td valign="top">';
942
+                $out.=$form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
943
+                $out.='</td>';
944
+                $out.= '<td>';
945
+                if ($this->withbodyreadonly)
946
+                {
947
+                    $out.= nl2br($defaultmessage);
948
+                    $out.= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
949
+                }
950
+                else
951
+                {
952
+                    if (! isset($this->ckeditortoolbar)) $this->ckeditortoolbar = 'dolibarr_notes';
953
+
954
+                    // Editor wysiwyg
955
+                    require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
956
+                    if ($this->withfckeditor == -1)
957
+                    {
958
+                        if (! empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor=1;
959
+                        else $this->withfckeditor=0;
960
+                    }
961
+
962
+                    $doleditor=new DolEditor('message',$defaultmessage,'',280,$this->ckeditortoolbar,'In',true,true,$this->withfckeditor,8,'95%');
963
+                    $out.= $doleditor->Create(1);
964
+                }
965
+                $out.= "</td></tr>\n";
966
+            }
967
+
968
+            $out.= '</table>'."\n";
969
+
970
+            if ($this->withform == 1 || $this->withform == -1)
971
+            {
972
+                $out.= '<br><div class="center">';
973
+                $out.= '<input class="button" type="submit" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
974
+                // Add a javascript test to avoid to forget to submit file before sending email
975
+                if ($this->withfile == 2 && $conf->use_javascript_ajax)
976
+                {
977
+                    $out.= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
978
+                }
979
+                $out.= ' />';
980
+                if ($this->withcancel)
981
+                {
982
+                    $out.= ' &nbsp; &nbsp; ';
983
+                    $out.= '<input class="button" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
984
+                }
985
+                $out.= '</div>'."\n";
986
+            }
987
+
988
+            if ($this->withform == 1) $out.= '</form>'."\n";
989
+
990
+            // Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
991
+            if (! empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY))
992
+            {
993
+                $out.= '<script type="text/javascript" language="javascript">';
994
+                $out.= 'jQuery(document).ready(function () {';
995
+                $out.= '	$(document).on("keypress", \'#mailform\', function (e) {		/* Note this is called at every key pressed ! */
996 996
 	    						var code = e.keyCode || e.which;
997 997
 	    						if (code == 13) {
998 998
 	        						e.preventDefault();
999 999
 	        						return false;
1000 1000
 	    						}
1001 1001
 							});';
1002
-				$out.='		})';
1003
-				$out.= '</script>';
1004
-			}
1005
-
1006
-			$out.= "<!-- End form mail -->\n";
1007
-
1008
-			return $out;
1009
-		}
1010
-	}
1011
-
1012
-	/**
1013
-	 * get html For WithCCC
1014
-	 *
1015
-	 * @return string html
1016
-	 */
1017
-	public function getHtmlForWithCcc()
1018
-	{
1019
-		global $conf, $langs, $form;
1020
-		$out = '<tr><td>';
1021
-		$out.= $form->textwithpicto($langs->trans("MailCCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1022
-		$out.= '</td><td>';
1023
-		if (! empty($this->withtocccreadonly)) {
1024
-			$out.= (! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))?$this->withtoccc:"";
1025
-		} else {
1026
-			$out.= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.((! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))? (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:$this->withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />';
1027
-			if (! empty($this->withtoccc) && is_array($this->withtoccc)) {
1028
-				$out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1029
-				// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1030
-				$tmparray = $this->withtoccc;
1031
-				foreach ($tmparray as $key => $val) {
1032
-					$tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
1033
-				}
1034
-				$withtocccselected=GETPOST("receiverccc");     // Array of selected value
1035
-				$out.= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, null, null, null,null, "90%");
1036
-			}
1037
-		}
1038
-
1039
-		$showinfobcc='';
1040
-		if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO;
1041
-		if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO;
1042
-		if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO;
1043
-		if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO;
1044
-		if ($showinfobcc) $out.=' + '.$showinfobcc;
1045
-		$out.= "</td></tr>\n";
1046
-		return $out;
1047
-	}
1048
-
1049
-	/**
1050
-	 * get Html For WithErrorsTo
1051
-	 *
1052
-	 * @return string html
1053
-	 */
1054
-	public function getHtmlForWithErrorsTo()
1055
-	{
1056
-		global $conf, $langs;
1057
-		//if (! $this->errorstomail) $this->errorstomail=$this->frommail;
1058
-		$errorstomail = (! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : $this->errorstomail);
1059
-		if ($this->witherrorstoreadonly) {
1060
-			$out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1061
-			$out = '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1062
-			$out.= $errorstomail;
1063
-			$out.= "</td></tr>\n";
1064
-		} else {
1065
-			$out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1066
-			$out.= '<input size="30" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1067
-			$out.= "</td></tr>\n";
1068
-		}
1069
-		return $out;
1070
-	}
1071
-
1072
-	/**
1073
-	 * get Html For Asking for Deliveriy Receipt
1074
-	 *
1075
-	 * @return string html
1076
-	 */
1077
-	public function getHtmlForDeliveryreceipt()
1078
-	{
1079
-		global $conf, $langs, $form;
1080
-		$out = '<tr><td>'.$langs->trans("DeliveryReceipt").'</td><td>';
1081
-
1082
-		if (! empty($this->withdeliveryreceiptreadonly)) {
1083
-			$out.= yn($this->withdeliveryreceipt);
1084
-		} else {
1085
-			$defaultvaluefordeliveryreceipt=0;
1086
-			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt=1;
1087
-			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt=1;
1088
-			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt=1;
1089
-			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt=1;
1090
-			$out.= $form->selectyesno('deliveryreceipt', (isset($_POST["deliveryreceipt"])?$_POST["deliveryreceipt"]:$defaultvaluefordeliveryreceipt), 1);
1091
-		}
1092
-		$out.= "</td></tr>\n";
1093
-		return $out;
1094
-	}
1095
-
1096
-	/**
1097
-	 * get Html For Topic of message
1098
-	 *
1099
-	 * @return string html
1100
-	 */
1101
-	public function getHtmlForTopic()
1102
-	{
1103
-		global $conf, $langs, $form;
1104
-		$defaulttopic = GETPOST('subject','none');
1105
-		if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1') {
1106
-			if ($arraydefaultmessage && $arraydefaultmessage->topic) {
1107
-				$defaulttopic = $arraydefaultmessage->topic;
1108
-			} elseif (! is_numeric($this->withtopic)) {
1109
-				$defaulttopic = $this->withtopic;
1110
-			}
1111
-		}
1112
-
1113
-		$defaulttopic=make_substitutions($defaulttopic,$this->substit);
1114
-
1115
-		$out = '<tr>';
1116
-		$out.= '<td class="fieldrequired">';
1117
-		$out.= $form->textwithpicto($langs->trans('MailTopic'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
1118
-		$out.= '</td>';
1119
-		$out.= '<td>';
1120
-		if ($this->withtopicreadonly) {
1121
-			$out.= $defaulttopic;
1122
-			$out.= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
1123
-		} else {
1124
-			$out.= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'. ((isset($_POST["subject"]) && ! $_POST['modelselected'])?$_POST["subject"]:($defaulttopic?$defaulttopic:'')) .'" />';
1125
-		}
1126
-		$out.= "</td></tr>\n";
1127
-		return $out;
1128
-	}
1129
-
1130
-	/**
1131
-	 *      Return templates of email with type = $type_template or type = 'all'.
1132
-	 *      This search into table c_email_templates. Used by the get_form function.
1133
-	 *
1134
-	 * 		@param	DoliDB		$db				Database handler
1135
-	 * 		@param	string		$type_template	Get message for model/type=$type_template, type='all' also included.
1136
-	 *      @param	string		$user			Get template public or limited to this user
1137
-	 *      @param	Translate	$outputlangs	Output lang object
1138
-	 *      @param	int			$id				Id of template to find, or -1 for first found with position 0, or 0 for first found whatever is position (priority order depends on lang provided or not) or -2 for exact match with label (no answer if not found)
1139
-	 *      @param  int         $active         1=Only active template, 0=Only disabled, -1=All
1140
-	 *      @param	string		$label			Label of template
1141
-	 *      @return ModelMail					One instance of ModelMail
1142
-	 */
1143
-	public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1, $label='')
1144
-	{
1145
-		$ret = new ModelMail();
1146
-
1147
-		if ($id == -2 && empty($label))
1148
-		{
1149
-			$this->error = 'LabelIsMandatoryWhenIdIs-2';
1150
-			return -1;
1151
-		}
1152
-
1153
-		$sql = "SELECT rowid, label, topic, joinfiles, content, content_lines, lang";
1154
-		$sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1155
-		$sql.= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')";
1156
-		$sql.= " AND entity IN (".getEntity('c_email_templates').")";
1157
-		$sql.= " AND (private = 0 OR fk_user = ".$user->id.")";				// Get all public or private owned
1158
-		if ($active >= 0) $sql.=" AND active = ".$active;
1159
-		if ($label) $sql.=" AND label ='".$db->escape($label)."'";
1160
-		if (! ($id > 0) && is_object($outputlangs)) $sql.= " AND (lang = '".$db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
1161
-		if ($id > 0)   $sql.= " AND rowid=".$id;
1162
-		if ($id == -1) $sql.= " AND position=0";
1163
-		if (is_object($outputlangs)) $sql.= $db->order("position,lang,label","ASC,DESC,ASC");		// We want line with lang set first, then with lang null or ''
1164
-		else $sql.= $db->order("position,lang,label","ASC,ASC,ASC");		// If no language provided, we give priority to lang not defined
1165
-		$sql.= $db->plimit(1);
1166
-		//print $sql;
1167
-
1168
-		$resql = $db->query($sql);
1169
-		if ($resql)
1170
-		{
1171
-			// Get first found
1172
-			$obj = $db->fetch_object($resql);
1173
-
1174
-			if ($obj) {
1175
-				$ret->id = $obj->rowid;
1176
-				$ret->label = $obj->label;
1177
-				$ret->lang = $obj->lang;
1178
-				$ret->topic = $obj->topic;
1179
-				$ret->content = $obj->content;
1180
-				$ret->content_lines = $obj->content_lines;
1181
-				$ret->joinfiles = $obj->joinfiles;
1182
-			}
1183
-			elseif($id == -2) {
1184
-				// Not found with the provided label
1185
-				return -1;
1186
-			}
1187
-			else {	// If there is no template at all
1188
-				$defaultmessage='';
1189
-				if ($type_template=='body')							{ $defaultmessage=$this->withbody; }		// Special case to use this->withbody as content
1190
-				elseif ($type_template=='facture_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoice"); }
1191
-				elseif ($type_template=='facture_relance')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder"); }
1192
-				elseif ($type_template=='propal_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendProposal"); }
1193
-				elseif ($type_template=='supplier_proposal_send')	{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal"); }
1194
-				elseif ($type_template=='order_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendOrder"); }
1195
-				elseif ($type_template=='order_supplier_send')		{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder"); }
1196
-				elseif ($type_template=='invoice_supplier_send')	{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice"); }
1197
-				elseif ($type_template=='shipping_send')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendShipping"); }
1198
-				elseif ($type_template=='fichinter_send')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendFichInter"); }
1199
-				elseif ($type_template=='thirdparty')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentThirdparty"); }
1200
-				elseif ($type_template=='user')				        { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentUser"); }
1201
-				elseif (!empty($type_template))				        { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContent".ucfirst($type_template)); }
1202
-
1203
-				$ret->label = 'default';
1204
-				$ret->lang = $outputlangs->defaultlang;
1205
-				$ret->topic = '';
1206
-				$ret->joinfiles = 1;
1207
-				$ret->content = $defaultmessage;
1208
-				$ret->content_lines ='';
1209
-			}
1210
-
1211
-			$db->free($resql);
1212
-			return $ret;
1213
-		}
1214
-		else
1215
-		{
1216
-			dol_print_error($db);
1217
-			return -1;
1218
-		}
1219
-	}
1220
-
1221
-	/**
1222
-	 *      Find if template exists
1223
-	 *      Search into table c_email_templates
1224
-	 *
1225
-	 * 		@param	string		$type_template	Get message for key module
1226
-	 *      @param	string		$user			Use template public or limited to this user
1227
-	 *      @param	Translate	$outputlangs	Output lang object
1228
-	 *      @return	int		<0 if KO,
1229
-	 */
1230
-	public function isEMailTemplate($type_template, $user, $outputlangs)
1231
-	{
1232
-		$ret=array();
1233
-
1234
-		$sql = "SELECT label, topic, content, lang";
1235
-		$sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1236
-		$sql.= " WHERE type_template='".$this->db->escape($type_template)."'";
1237
-		$sql.= " AND entity IN (".getEntity('c_email_templates').")";
1238
-		$sql.= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
1239
-		if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
1240
-		$sql.= $this->db->order("lang,label","ASC");
1241
-		//print $sql;
1242
-
1243
-		$resql = $this->db->query($sql);
1244
-		if ($resql)
1245
-		{
1246
-			$num= $this->db->num_rows($resql);
1247
-			$this->db->free($resql);
1248
-			return $num;
1249
-		}
1250
-		else
1251
-		{
1252
-			$this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1253
-			return -1;
1254
-		}
1255
-	}
1256
-
1257
-	/**
1258
-	 *      Find if template exists and are available for current user, then set them into $this->lines_module.
1259
-	 *      Search into table c_email_templates
1260
-	 *
1261
-	 * 		@param	string		$type_template	Get message for key module
1262
-	 *      @param	string		$user			Use template public or limited to this user
1263
-	 *      @param	Translate	$outputlangs	Output lang object
1264
-	 *      @param  int         $active         1=Only active template, 0=Only disabled, -1=All
1265
-	 *      @return	int		                    <0 if KO, nb of records found if OK
1266
-	 */
1267
-	public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active=1)
1268
-	{
1269
-		$ret=array();
1270
-
1271
-		$sql = "SELECT rowid, label, topic, content, content_lines, lang, fk_user, private, position";
1272
-		$sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1273
-		$sql.= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1274
-		$sql.= " AND entity IN (".getEntity('c_email_templates').")";
1275
-		$sql.= " AND (private = 0 OR fk_user = ".$user->id.")";		// See all public templates or templates I own.
1276
-		if ($active >= 0) $sql.=" AND active = ".$active;
1277
-		//if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";	// Return all languages
1278
-		$sql.= $this->db->order("position,lang,label","ASC");
1279
-		//print $sql;
1280
-
1281
-		$resql = $this->db->query($sql);
1282
-		if ($resql)
1283
-		{
1284
-			$num=$this->db->num_rows($resql);
1285
-			$this->lines_model=array();
1286
-			while ($obj = $this->db->fetch_object($resql))
1287
-			{
1288
-				$line = new ModelMail();
1289
-				$line->id=$obj->rowid;
1290
-				$line->label=$obj->label;
1291
-				$line->lang=$obj->lang;
1292
-				$line->fk_user=$obj->fk_user;
1293
-				$line->private=$obj->private;
1294
-				$line->position=$obj->position;
1295
-				$line->topic=$obj->topic;
1296
-				$line->content=$obj->content;
1297
-				$line->content_lines=$obj->content_lines;
1298
-
1299
-				$this->lines_model[]=$line;
1300
-			}
1301
-			$this->db->free($resql);
1302
-			return $num;
1303
-		}
1304
-		else
1305
-		{
1306
-			$this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1307
-			return -1;
1308
-		}
1309
-	}
1310
-
1311
-
1312
-
1313
-	/**
1314
-	 * Set substit array from object. This is call when suggesting the email template into forms before sending email.
1315
-	 *
1316
-	 * @param	CommonObject	$object		   Object to use
1317
-	 * @param   Translate  		$outputlangs   Object lang
1318
-	 * @return	void
1319
-	 * @see getCommonSubstitutionArray
1320
-	 */
1321
-	function setSubstitFromObject($object, $outputlangs)
1322
-	{
1323
-		global $conf, $user;
1324
-
1325
-		$parameters=array();
1326
-		$tmparray=getCommonSubstitutionArray($outputlangs, 0, null, $object);
1327
-		complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
1328
-
1329
-		$this->substit=$tmparray;
1330
-
1331
-		// Fill substit_lines with each object lines content
1332
-		if (is_array($object->lines))
1333
-		{
1334
-			foreach ($object->lines as $line)
1335
-			{
1336
-				$substit_line = array(
1337
-					'__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1338
-					'__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1339
-					'__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1340
-					'__LABEL__' => isset($line->label) ? $line->label : '',
1341
-					'__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1342
-					'__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
1343
-					'__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
1344
-					'__QUANTITY__' => $line->qty,
1345
-					'__SUBPRICE__' => price($line->subprice),
1346
-					'__AMOUNT__' => price($line->total_ttc),
1347
-					'__AMOUNT_EXCL_TAX__' => price($line->total_ht)
1348
-				);
1349
-
1350
-				// Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1351
-				if (!empty($line->fk_product))
1352
-				{
1353
-					if (! is_object($extrafields)) $extrafields = new ExtraFields($this->db);
1354
-					$extrafields->fetch_name_optionals_label('product', true);
1355
-					$product = new Product($this->db);
1356
-					$product->fetch($line->fk_product, '', '', 1);
1357
-					$product->fetch_optionals();
1358
-					if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
1359
-					{
1360
-						foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
1361
-							$substit_line['__PRODUCT_EXTRAFIELD_' . strtoupper($key) . '__'] = $product->array_options['options_' . $key];
1362
-						}
1363
-					}
1364
-				}
1365
-				$this->substit_lines[] = $substit_line;
1366
-			}
1367
-		}
1368
-	}
1369
-
1370
-	/**
1371
-	 * Get list of substitution keys available for emails. This is used for tooltips help.
1372
-	 * This include the complete_substitutions_array.
1373
-	 *
1374
-	 * @param	string	$mode		'formemail', 'formemailwithlines', 'formemailforlines', 'emailing', ...
1375
-	 * @param	Object	$object		Object if applicable
1376
-	 * @return	array               Array of substitution values for emails.
1377
-	 */
1378
-	static function getAvailableSubstitKey($mode='formemail', $object=null)
1379
-	{
1380
-		global $conf, $langs;
1381
-
1382
-		$tmparray=array();
1383
-		if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines')
1384
-		{
1385
-			$parameters=array('mode'=>$mode);
1386
-			$tmparray=getCommonSubstitutionArray($langs, 2, null, $object);			// Note: On email templated edition, this is null because it is related to all type of objects
1387
-			complete_substitutions_array($tmparray, $langs, null, $parameters);
1388
-
1389
-			if ($mode == 'formwithlines')
1390
-			{
1391
-				$tmparray['__LINES__'] = '__LINES__';      // Will be set by the get_form function
1392
-			}
1393
-			if ($mode == 'formforlines')
1394
-			{
1395
-				$tmparray['__QUANTITY__'] = '__QUANTITY__';   // Will be set by the get_form function
1396
-			}
1397
-		}
1398
-
1399
-		if ($mode == 'emailing')
1400
-		{
1401
-			$parameters=array('mode'=>$mode);
1402
-			$tmparray=getCommonSubstitutionArray($langs, 2, array('object','objectamount'), $object);			// Note: On email templated edition, this is null because it is related to all type of objects
1403
-			complete_substitutions_array($tmparray, $langs, null, $parameters);
1404
-
1405
-			// For mass emailing, we have different keys
1406
-			$tmparray['__ID__'] = 'IdRecord';
1407
-			$tmparray['__EMAIL__'] = 'EMailRecipient';
1408
-			$tmparray['__LASTNAME__'] = 'Lastname';
1409
-			$tmparray['__FIRSTNAME__'] = 'Firstname';
1410
-			$tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
1411
-			$tmparray['__OTHER1__'] = 'Other1';
1412
-			$tmparray['__OTHER2__'] = 'Other2';
1413
-			$tmparray['__OTHER3__'] = 'Other3';
1414
-			$tmparray['__OTHER4__'] = 'Other4';
1415
-			$tmparray['__OTHER5__'] = 'Other5';
1416
-			$tmparray['__USER_SIGNATURE__'] = 'TagSignature';
1417
-			$tmparray['__CHECK_READ__'] = 'TagCheckMail';
1418
-			$tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe';
1419
-				//,'__PERSONALIZED__' => 'Personalized'	// Hidden because not used yet in mass emailing
1420
-
1421
-			$onlinepaymentenabled = 0;
1422
-			if (! empty($conf->paypal->enabled)) $onlinepaymentenabled++;
1423
-			if (! empty($conf->paybox->enabled)) $onlinepaymentenabled++;
1424
-			if (! empty($conf->stripe->enabled)) $onlinepaymentenabled++;
1425
-			if ($onlinepaymentenabled && ! empty($conf->global->PAYMENT_SECURITY_TOKEN))
1426
-			{
1427
-				$tmparray['__SECUREKEYPAYMENT__']=$conf->global->PAYMENT_SECURITY_TOKEN;
1428
-				if (! empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE))
1429
-				{
1430
-					if ($conf->adherent->enabled) $tmparray['__SECUREKEYPAYMENT_MEMBER__']='SecureKeyPAYMENTUniquePerMember';
1431
-					if ($conf->facture->enabled)  $tmparray['__SECUREKEYPAYMENT_INVOICE__']='SecureKeyPAYMENTUniquePerInvoice';
1432
-					if ($conf->commande->enabled) $tmparray['__SECUREKEYPAYMENT_ORDER__']='SecureKeyPAYMENTUniquePerOrder';
1433
-					if ($conf->contrat->enabled)  $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__']='SecureKeyPAYMENTUniquePerContractLine';
1434
-				}
1435
-			}
1436
-			else
1437
-			{
1438
-				/* No need to show into tooltip help, option is not enabled
1002
+                $out.='		})';
1003
+                $out.= '</script>';
1004
+            }
1005
+
1006
+            $out.= "<!-- End form mail -->\n";
1007
+
1008
+            return $out;
1009
+        }
1010
+    }
1011
+
1012
+    /**
1013
+     * get html For WithCCC
1014
+     *
1015
+     * @return string html
1016
+     */
1017
+    public function getHtmlForWithCcc()
1018
+    {
1019
+        global $conf, $langs, $form;
1020
+        $out = '<tr><td>';
1021
+        $out.= $form->textwithpicto($langs->trans("MailCCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
1022
+        $out.= '</td><td>';
1023
+        if (! empty($this->withtocccreadonly)) {
1024
+            $out.= (! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))?$this->withtoccc:"";
1025
+        } else {
1026
+            $out.= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.((! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))? (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:$this->withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />';
1027
+            if (! empty($this->withtoccc) && is_array($this->withtoccc)) {
1028
+                $out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
1029
+                // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
1030
+                $tmparray = $this->withtoccc;
1031
+                foreach ($tmparray as $key => $val) {
1032
+                    $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
1033
+                }
1034
+                $withtocccselected=GETPOST("receiverccc");     // Array of selected value
1035
+                $out.= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, null, null, null,null, "90%");
1036
+            }
1037
+        }
1038
+
1039
+        $showinfobcc='';
1040
+        if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO;
1041
+        if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO;
1042
+        if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO;
1043
+        if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $showinfobcc=$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO;
1044
+        if ($showinfobcc) $out.=' + '.$showinfobcc;
1045
+        $out.= "</td></tr>\n";
1046
+        return $out;
1047
+    }
1048
+
1049
+    /**
1050
+     * get Html For WithErrorsTo
1051
+     *
1052
+     * @return string html
1053
+     */
1054
+    public function getHtmlForWithErrorsTo()
1055
+    {
1056
+        global $conf, $langs;
1057
+        //if (! $this->errorstomail) $this->errorstomail=$this->frommail;
1058
+        $errorstomail = (! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : $this->errorstomail);
1059
+        if ($this->witherrorstoreadonly) {
1060
+            $out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1061
+            $out = '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1062
+            $out.= $errorstomail;
1063
+            $out.= "</td></tr>\n";
1064
+        } else {
1065
+            $out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
1066
+            $out.= '<input size="30" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
1067
+            $out.= "</td></tr>\n";
1068
+        }
1069
+        return $out;
1070
+    }
1071
+
1072
+    /**
1073
+     * get Html For Asking for Deliveriy Receipt
1074
+     *
1075
+     * @return string html
1076
+     */
1077
+    public function getHtmlForDeliveryreceipt()
1078
+    {
1079
+        global $conf, $langs, $form;
1080
+        $out = '<tr><td>'.$langs->trans("DeliveryReceipt").'</td><td>';
1081
+
1082
+        if (! empty($this->withdeliveryreceiptreadonly)) {
1083
+            $out.= yn($this->withdeliveryreceipt);
1084
+        } else {
1085
+            $defaultvaluefordeliveryreceipt=0;
1086
+            if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt=1;
1087
+            if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt=1;
1088
+            if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt=1;
1089
+            if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt=1;
1090
+            $out.= $form->selectyesno('deliveryreceipt', (isset($_POST["deliveryreceipt"])?$_POST["deliveryreceipt"]:$defaultvaluefordeliveryreceipt), 1);
1091
+        }
1092
+        $out.= "</td></tr>\n";
1093
+        return $out;
1094
+    }
1095
+
1096
+    /**
1097
+     * get Html For Topic of message
1098
+     *
1099
+     * @return string html
1100
+     */
1101
+    public function getHtmlForTopic()
1102
+    {
1103
+        global $conf, $langs, $form;
1104
+        $defaulttopic = GETPOST('subject','none');
1105
+        if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1') {
1106
+            if ($arraydefaultmessage && $arraydefaultmessage->topic) {
1107
+                $defaulttopic = $arraydefaultmessage->topic;
1108
+            } elseif (! is_numeric($this->withtopic)) {
1109
+                $defaulttopic = $this->withtopic;
1110
+            }
1111
+        }
1112
+
1113
+        $defaulttopic=make_substitutions($defaulttopic,$this->substit);
1114
+
1115
+        $out = '<tr>';
1116
+        $out.= '<td class="fieldrequired">';
1117
+        $out.= $form->textwithpicto($langs->trans('MailTopic'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
1118
+        $out.= '</td>';
1119
+        $out.= '<td>';
1120
+        if ($this->withtopicreadonly) {
1121
+            $out.= $defaulttopic;
1122
+            $out.= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
1123
+        } else {
1124
+            $out.= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'. ((isset($_POST["subject"]) && ! $_POST['modelselected'])?$_POST["subject"]:($defaulttopic?$defaulttopic:'')) .'" />';
1125
+        }
1126
+        $out.= "</td></tr>\n";
1127
+        return $out;
1128
+    }
1129
+
1130
+    /**
1131
+     *      Return templates of email with type = $type_template or type = 'all'.
1132
+     *      This search into table c_email_templates. Used by the get_form function.
1133
+     *
1134
+     * 		@param	DoliDB		$db				Database handler
1135
+     * 		@param	string		$type_template	Get message for model/type=$type_template, type='all' also included.
1136
+     *      @param	string		$user			Get template public or limited to this user
1137
+     *      @param	Translate	$outputlangs	Output lang object
1138
+     *      @param	int			$id				Id of template to find, or -1 for first found with position 0, or 0 for first found whatever is position (priority order depends on lang provided or not) or -2 for exact match with label (no answer if not found)
1139
+     *      @param  int         $active         1=Only active template, 0=Only disabled, -1=All
1140
+     *      @param	string		$label			Label of template
1141
+     *      @return ModelMail					One instance of ModelMail
1142
+     */
1143
+    public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1, $label='')
1144
+    {
1145
+        $ret = new ModelMail();
1146
+
1147
+        if ($id == -2 && empty($label))
1148
+        {
1149
+            $this->error = 'LabelIsMandatoryWhenIdIs-2';
1150
+            return -1;
1151
+        }
1152
+
1153
+        $sql = "SELECT rowid, label, topic, joinfiles, content, content_lines, lang";
1154
+        $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1155
+        $sql.= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')";
1156
+        $sql.= " AND entity IN (".getEntity('c_email_templates').")";
1157
+        $sql.= " AND (private = 0 OR fk_user = ".$user->id.")";				// Get all public or private owned
1158
+        if ($active >= 0) $sql.=" AND active = ".$active;
1159
+        if ($label) $sql.=" AND label ='".$db->escape($label)."'";
1160
+        if (! ($id > 0) && is_object($outputlangs)) $sql.= " AND (lang = '".$db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
1161
+        if ($id > 0)   $sql.= " AND rowid=".$id;
1162
+        if ($id == -1) $sql.= " AND position=0";
1163
+        if (is_object($outputlangs)) $sql.= $db->order("position,lang,label","ASC,DESC,ASC");		// We want line with lang set first, then with lang null or ''
1164
+        else $sql.= $db->order("position,lang,label","ASC,ASC,ASC");		// If no language provided, we give priority to lang not defined
1165
+        $sql.= $db->plimit(1);
1166
+        //print $sql;
1167
+
1168
+        $resql = $db->query($sql);
1169
+        if ($resql)
1170
+        {
1171
+            // Get first found
1172
+            $obj = $db->fetch_object($resql);
1173
+
1174
+            if ($obj) {
1175
+                $ret->id = $obj->rowid;
1176
+                $ret->label = $obj->label;
1177
+                $ret->lang = $obj->lang;
1178
+                $ret->topic = $obj->topic;
1179
+                $ret->content = $obj->content;
1180
+                $ret->content_lines = $obj->content_lines;
1181
+                $ret->joinfiles = $obj->joinfiles;
1182
+            }
1183
+            elseif($id == -2) {
1184
+                // Not found with the provided label
1185
+                return -1;
1186
+            }
1187
+            else {	// If there is no template at all
1188
+                $defaultmessage='';
1189
+                if ($type_template=='body')							{ $defaultmessage=$this->withbody; }		// Special case to use this->withbody as content
1190
+                elseif ($type_template=='facture_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoice"); }
1191
+                elseif ($type_template=='facture_relance')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder"); }
1192
+                elseif ($type_template=='propal_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendProposal"); }
1193
+                elseif ($type_template=='supplier_proposal_send')	{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal"); }
1194
+                elseif ($type_template=='order_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendOrder"); }
1195
+                elseif ($type_template=='order_supplier_send')		{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder"); }
1196
+                elseif ($type_template=='invoice_supplier_send')	{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice"); }
1197
+                elseif ($type_template=='shipping_send')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendShipping"); }
1198
+                elseif ($type_template=='fichinter_send')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendFichInter"); }
1199
+                elseif ($type_template=='thirdparty')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentThirdparty"); }
1200
+                elseif ($type_template=='user')				        { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentUser"); }
1201
+                elseif (!empty($type_template))				        { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContent".ucfirst($type_template)); }
1202
+
1203
+                $ret->label = 'default';
1204
+                $ret->lang = $outputlangs->defaultlang;
1205
+                $ret->topic = '';
1206
+                $ret->joinfiles = 1;
1207
+                $ret->content = $defaultmessage;
1208
+                $ret->content_lines ='';
1209
+            }
1210
+
1211
+            $db->free($resql);
1212
+            return $ret;
1213
+        }
1214
+        else
1215
+        {
1216
+            dol_print_error($db);
1217
+            return -1;
1218
+        }
1219
+    }
1220
+
1221
+    /**
1222
+     *      Find if template exists
1223
+     *      Search into table c_email_templates
1224
+     *
1225
+     * 		@param	string		$type_template	Get message for key module
1226
+     *      @param	string		$user			Use template public or limited to this user
1227
+     *      @param	Translate	$outputlangs	Output lang object
1228
+     *      @return	int		<0 if KO,
1229
+     */
1230
+    public function isEMailTemplate($type_template, $user, $outputlangs)
1231
+    {
1232
+        $ret=array();
1233
+
1234
+        $sql = "SELECT label, topic, content, lang";
1235
+        $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1236
+        $sql.= " WHERE type_template='".$this->db->escape($type_template)."'";
1237
+        $sql.= " AND entity IN (".getEntity('c_email_templates').")";
1238
+        $sql.= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
1239
+        if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
1240
+        $sql.= $this->db->order("lang,label","ASC");
1241
+        //print $sql;
1242
+
1243
+        $resql = $this->db->query($sql);
1244
+        if ($resql)
1245
+        {
1246
+            $num= $this->db->num_rows($resql);
1247
+            $this->db->free($resql);
1248
+            return $num;
1249
+        }
1250
+        else
1251
+        {
1252
+            $this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1253
+            return -1;
1254
+        }
1255
+    }
1256
+
1257
+    /**
1258
+     *      Find if template exists and are available for current user, then set them into $this->lines_module.
1259
+     *      Search into table c_email_templates
1260
+     *
1261
+     * 		@param	string		$type_template	Get message for key module
1262
+     *      @param	string		$user			Use template public or limited to this user
1263
+     *      @param	Translate	$outputlangs	Output lang object
1264
+     *      @param  int         $active         1=Only active template, 0=Only disabled, -1=All
1265
+     *      @return	int		                    <0 if KO, nb of records found if OK
1266
+     */
1267
+    public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active=1)
1268
+    {
1269
+        $ret=array();
1270
+
1271
+        $sql = "SELECT rowid, label, topic, content, content_lines, lang, fk_user, private, position";
1272
+        $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1273
+        $sql.= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1274
+        $sql.= " AND entity IN (".getEntity('c_email_templates').")";
1275
+        $sql.= " AND (private = 0 OR fk_user = ".$user->id.")";		// See all public templates or templates I own.
1276
+        if ($active >= 0) $sql.=" AND active = ".$active;
1277
+        //if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";	// Return all languages
1278
+        $sql.= $this->db->order("position,lang,label","ASC");
1279
+        //print $sql;
1280
+
1281
+        $resql = $this->db->query($sql);
1282
+        if ($resql)
1283
+        {
1284
+            $num=$this->db->num_rows($resql);
1285
+            $this->lines_model=array();
1286
+            while ($obj = $this->db->fetch_object($resql))
1287
+            {
1288
+                $line = new ModelMail();
1289
+                $line->id=$obj->rowid;
1290
+                $line->label=$obj->label;
1291
+                $line->lang=$obj->lang;
1292
+                $line->fk_user=$obj->fk_user;
1293
+                $line->private=$obj->private;
1294
+                $line->position=$obj->position;
1295
+                $line->topic=$obj->topic;
1296
+                $line->content=$obj->content;
1297
+                $line->content_lines=$obj->content_lines;
1298
+
1299
+                $this->lines_model[]=$line;
1300
+            }
1301
+            $this->db->free($resql);
1302
+            return $num;
1303
+        }
1304
+        else
1305
+        {
1306
+            $this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1307
+            return -1;
1308
+        }
1309
+    }
1310
+
1311
+
1312
+
1313
+    /**
1314
+     * Set substit array from object. This is call when suggesting the email template into forms before sending email.
1315
+     *
1316
+     * @param	CommonObject	$object		   Object to use
1317
+     * @param   Translate  		$outputlangs   Object lang
1318
+     * @return	void
1319
+     * @see getCommonSubstitutionArray
1320
+     */
1321
+    function setSubstitFromObject($object, $outputlangs)
1322
+    {
1323
+        global $conf, $user;
1324
+
1325
+        $parameters=array();
1326
+        $tmparray=getCommonSubstitutionArray($outputlangs, 0, null, $object);
1327
+        complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
1328
+
1329
+        $this->substit=$tmparray;
1330
+
1331
+        // Fill substit_lines with each object lines content
1332
+        if (is_array($object->lines))
1333
+        {
1334
+            foreach ($object->lines as $line)
1335
+            {
1336
+                $substit_line = array(
1337
+                    '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1338
+                    '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1339
+                    '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1340
+                    '__LABEL__' => isset($line->label) ? $line->label : '',
1341
+                    '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1342
+                    '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
1343
+                    '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
1344
+                    '__QUANTITY__' => $line->qty,
1345
+                    '__SUBPRICE__' => price($line->subprice),
1346
+                    '__AMOUNT__' => price($line->total_ttc),
1347
+                    '__AMOUNT_EXCL_TAX__' => price($line->total_ht)
1348
+                );
1349
+
1350
+                // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1351
+                if (!empty($line->fk_product))
1352
+                {
1353
+                    if (! is_object($extrafields)) $extrafields = new ExtraFields($this->db);
1354
+                    $extrafields->fetch_name_optionals_label('product', true);
1355
+                    $product = new Product($this->db);
1356
+                    $product->fetch($line->fk_product, '', '', 1);
1357
+                    $product->fetch_optionals();
1358
+                    if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
1359
+                    {
1360
+                        foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
1361
+                            $substit_line['__PRODUCT_EXTRAFIELD_' . strtoupper($key) . '__'] = $product->array_options['options_' . $key];
1362
+                        }
1363
+                    }
1364
+                }
1365
+                $this->substit_lines[] = $substit_line;
1366
+            }
1367
+        }
1368
+    }
1369
+
1370
+    /**
1371
+     * Get list of substitution keys available for emails. This is used for tooltips help.
1372
+     * This include the complete_substitutions_array.
1373
+     *
1374
+     * @param	string	$mode		'formemail', 'formemailwithlines', 'formemailforlines', 'emailing', ...
1375
+     * @param	Object	$object		Object if applicable
1376
+     * @return	array               Array of substitution values for emails.
1377
+     */
1378
+    static function getAvailableSubstitKey($mode='formemail', $object=null)
1379
+    {
1380
+        global $conf, $langs;
1381
+
1382
+        $tmparray=array();
1383
+        if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines')
1384
+        {
1385
+            $parameters=array('mode'=>$mode);
1386
+            $tmparray=getCommonSubstitutionArray($langs, 2, null, $object);			// Note: On email templated edition, this is null because it is related to all type of objects
1387
+            complete_substitutions_array($tmparray, $langs, null, $parameters);
1388
+
1389
+            if ($mode == 'formwithlines')
1390
+            {
1391
+                $tmparray['__LINES__'] = '__LINES__';      // Will be set by the get_form function
1392
+            }
1393
+            if ($mode == 'formforlines')
1394
+            {
1395
+                $tmparray['__QUANTITY__'] = '__QUANTITY__';   // Will be set by the get_form function
1396
+            }
1397
+        }
1398
+
1399
+        if ($mode == 'emailing')
1400
+        {
1401
+            $parameters=array('mode'=>$mode);
1402
+            $tmparray=getCommonSubstitutionArray($langs, 2, array('object','objectamount'), $object);			// Note: On email templated edition, this is null because it is related to all type of objects
1403
+            complete_substitutions_array($tmparray, $langs, null, $parameters);
1404
+
1405
+            // For mass emailing, we have different keys
1406
+            $tmparray['__ID__'] = 'IdRecord';
1407
+            $tmparray['__EMAIL__'] = 'EMailRecipient';
1408
+            $tmparray['__LASTNAME__'] = 'Lastname';
1409
+            $tmparray['__FIRSTNAME__'] = 'Firstname';
1410
+            $tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
1411
+            $tmparray['__OTHER1__'] = 'Other1';
1412
+            $tmparray['__OTHER2__'] = 'Other2';
1413
+            $tmparray['__OTHER3__'] = 'Other3';
1414
+            $tmparray['__OTHER4__'] = 'Other4';
1415
+            $tmparray['__OTHER5__'] = 'Other5';
1416
+            $tmparray['__USER_SIGNATURE__'] = 'TagSignature';
1417
+            $tmparray['__CHECK_READ__'] = 'TagCheckMail';
1418
+            $tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe';
1419
+                //,'__PERSONALIZED__' => 'Personalized'	// Hidden because not used yet in mass emailing
1420
+
1421
+            $onlinepaymentenabled = 0;
1422
+            if (! empty($conf->paypal->enabled)) $onlinepaymentenabled++;
1423
+            if (! empty($conf->paybox->enabled)) $onlinepaymentenabled++;
1424
+            if (! empty($conf->stripe->enabled)) $onlinepaymentenabled++;
1425
+            if ($onlinepaymentenabled && ! empty($conf->global->PAYMENT_SECURITY_TOKEN))
1426
+            {
1427
+                $tmparray['__SECUREKEYPAYMENT__']=$conf->global->PAYMENT_SECURITY_TOKEN;
1428
+                if (! empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE))
1429
+                {
1430
+                    if ($conf->adherent->enabled) $tmparray['__SECUREKEYPAYMENT_MEMBER__']='SecureKeyPAYMENTUniquePerMember';
1431
+                    if ($conf->facture->enabled)  $tmparray['__SECUREKEYPAYMENT_INVOICE__']='SecureKeyPAYMENTUniquePerInvoice';
1432
+                    if ($conf->commande->enabled) $tmparray['__SECUREKEYPAYMENT_ORDER__']='SecureKeyPAYMENTUniquePerOrder';
1433
+                    if ($conf->contrat->enabled)  $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__']='SecureKeyPAYMENTUniquePerContractLine';
1434
+                }
1435
+            }
1436
+            else
1437
+            {
1438
+                /* No need to show into tooltip help, option is not enabled
1439 1439
 				$vars['__SECUREKEYPAYMENT__']='';
1440 1440
 				$vars['__SECUREKEYPAYMENT_MEMBER__']='';
1441 1441
 				$vars['__SECUREKEYPAYMENT_INVOICE__']='';
1442 1442
 				$vars['__SECUREKEYPAYMENT_ORDER__']='';
1443 1443
 				$vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
1444 1444
 				*/
1445
-			}
1446
-		}
1445
+            }
1446
+        }
1447 1447
 
1448
-		foreach($tmparray as $key => $val)
1449
-		{
1450
-			if (empty($val)) $tmparray[$key]=$key;
1451
-		}
1448
+        foreach($tmparray as $key => $val)
1449
+        {
1450
+            if (empty($val)) $tmparray[$key]=$key;
1451
+        }
1452 1452
 
1453
-		return $tmparray;
1454
-	}
1453
+        return $tmparray;
1454
+    }
1455 1455
 }
1456 1456
 
1457 1457
 
@@ -1460,19 +1460,19 @@  discard block
 block discarded – undo
1460 1460
  */
1461 1461
 class ModelMail
1462 1462
 {
1463
-	/**
1464
-	 * @var int ID
1465
-	 */
1466
-	public $id;
1463
+    /**
1464
+     * @var int ID
1465
+     */
1466
+    public $id;
1467 1467
 
1468
-	/**
1468
+    /**
1469 1469
      * @var string Model mail label
1470 1470
      */
1471 1471
     public $label;
1472 1472
 
1473
-	public $topic;
1474
-	public $content;
1475
-	public $content_lines;
1476
-	public $lang;
1477
-	public $joinfiles;
1473
+    public $topic;
1474
+    public $content;
1475
+    public $content_lines;
1476
+    public $lang;
1477
+    public $joinfiles;
1478 1478
 }
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.