Test Failed
Branch develop (8578a1)
by
unknown
25:54
created

FormMail::show_form()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2005-2012 Laurent Destailleur  <[email protected]>
3
 * Copyright (C) 2005-2012 Regis Houssin		<[email protected]>
4
 * Copyright (C) 2010-2011 Juanjo Menent		<[email protected]>
5
 * Copyright (C) 2015      Marcos García        <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
/**
22
 *       \file       htdocs/core/class/html.formmail.class.php
23
 *       \ingroup    core
24
 *       \brief      Fichier de la classe permettant la generation du formulaire html d'envoi de mail unitaire
25
 */
26
require_once DOL_DOCUMENT_ROOT .'/core/class/html.form.class.php';
27
28
29
/**
30
 *      Classe permettant la generation du formulaire html d'envoi de mail unitaire
31
 *      Usage: $formail = new FormMail($db)
32
 *             $formmail->proprietes=1 ou chaine ou tableau de valeurs
33
 *             $formmail->show_form() affiche le formulaire
34
 */
35
class FormMail extends Form
36
{
37
    var $db;
38
39
    var $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
40
41
    var $fromname;
42
    var $frommail;
43
    var $replytoname;
44
    var $replytomail;
45
    var $toname;
46
    var $tomail;
47
	var $trackid;
48
49
    var $withsubstit;			// Show substitution array
50
    var $withfrom;
51
	/**
52
	 * @var int
53
	 * @deprecated Fill withto with array before calling method.
54
	 * @see withto
55
	 */
56
	public $withtosocid;
57
	/**
58
	 * @var int|int[]
59
	 */
60
    public $withto;				// Show recipient emails
61
    var $withtofree;			// Show free text for recipient emails
62
    var $withtocc;
63
    var $withtoccc;
64
    var $withtopic;
65
    var $withfile;				// 0=No attaches files, 1=Show attached files, 2=Can add new attached files
66
    var $withmaindocfile;		// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
67
    var $withbody;
68
69
    var $withfromreadonly;
70
    var $withreplytoreadonly;
71
    var $withtoreadonly;
72
    var $withtoccreadonly;
73
	var $withtocccreadonly;
74
	var $withtopicreadonly;
75
    var $withfilereadonly;
76
    var $withdeliveryreceipt;
77
    var $withcancel;
78
    var $withfckeditor;
79
80
    var $substit=array();
81
    var $substit_lines=array();
82
    var $param=array();
83
84
    var $error;
85
86
    public $lines_model;
87
88
89
    /**
90
     *	Constructor
91
     *
92
     *  @param	DoliDB	$db      Database handler
93
     */
94
    function __construct($db)
95
    {
96
        $this->db = $db;
97
98
        $this->withform=1;
99
100
        $this->withfrom=1;
101
        $this->withto=1;
102
        $this->withtofree=1;
103
        $this->withtocc=1;
104
        $this->withtoccc=0;
105
        $this->witherrorsto=0;
106
        $this->withtopic=1;
107
        $this->withfile=0;			// 1=Add section "Attached files". 2=Can add files.
108
        $this->withmaindocfile=0;	// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
109
        $this->withbody=1;
110
111
        $this->withfromreadonly=1;
112
        $this->withreplytoreadonly=1;
113
        $this->withtoreadonly=0;
114
        $this->withtoccreadonly=0;
115
	    $this->withtocccreadonly=0;
116
        $this->witherrorstoreadonly=0;
117
        $this->withtopicreadonly=0;
118
        $this->withfilereadonly=0;
119
        $this->withbodyreadonly=0;
120
        $this->withdeliveryreceiptreadonly=0;
121
        $this->withfckeditor=-1;	// -1 = Auto
122
123
        return 1;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
124
    }
125
126
    /**
127
     * Clear list of attached files in send mail form (also stored in session)
128
     *
129
     * @return	void
130
     */
131
    function clear_attached_files()
132
    {
133
        global $conf,$user;
134
        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
135
136
        // Set tmp user directory
137
        $vardir=$conf->user->dir_output."/".$user->id;
138
        $upload_dir = $vardir.'/temp/';                     // TODO Add $keytoavoidconflict in upload_dir path
139
        if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir);
140
141
        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
142
        unset($_SESSION["listofpaths".$keytoavoidconflict]);
143
        unset($_SESSION["listofnames".$keytoavoidconflict]);
144
        unset($_SESSION["listofmimes".$keytoavoidconflict]);
145
    }
146
147
    /**
148
     * Add a file into the list of attached files (stored in SECTION array)
149
     *
150
     * @param 	string   $path   Full absolute path on filesystem of file, including file name
151
     * @param 	string   $file   Only filename
152
     * @param 	string   $type   Mime type
153
     * @return	void
154
     */
155
    function add_attached_files($path,$file,$type)
156
    {
157
        $listofpaths=array();
158
        $listofnames=array();
159
        $listofmimes=array();
160
161
        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
162
        if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
163
        if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
164
        if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
165
        if (! in_array($file,$listofnames))
166
        {
167
            $listofpaths[]=$path;
168
            $listofnames[]=$file;
169
            $listofmimes[]=$type;
170
            $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
171
            $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
172
            $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
173
        }
174
    }
175
176
    /**
177
     * Remove a file from the list of attached files (stored in SECTION array)
178
     *
179
     * @param  	string	$keytodelete     Key in file array (0, 1, 2, ...)
180
     * @return	void
181
     */
182
    function remove_attached_files($keytodelete)
183
    {
184
        $listofpaths=array();
185
        $listofnames=array();
186
        $listofmimes=array();
187
188
        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
189
        if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
190
        if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
191
        if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
192
        if ($keytodelete >= 0)
193
        {
194
            unset ($listofpaths[$keytodelete]);
195
            unset ($listofnames[$keytodelete]);
196
            unset ($listofmimes[$keytodelete]);
197
            $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
198
            $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
199
            $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
200
            //var_dump($_SESSION['listofpaths']);
201
        }
202
    }
203
204
    /**
205
     * Return list of attached files (stored in SECTION array)
206
     *
207
     * @return	array       array('paths'=> ,'names'=>, 'mimes'=> )
208
     */
209
    function get_attached_files()
210
    {
211
        $listofpaths=array();
212
        $listofnames=array();
213
        $listofmimes=array();
214
215
        $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
216
        if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
217
        if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
218
        if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
219
        return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
220
    }
221
222
    /**
223
     *	Show the form to input an email
224
     *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
225
     *  this->withmaindocfile
226
     *
227
     *	@param	string	$addfileaction		Name of action when posting file attachments
228
     *	@param	string	$removefileaction	Name of action when removing file attachments
229
     *	@return	void
230
     */
231
    function show_form($addfileaction='addfile',$removefileaction='removefile')
232
    {
233
        print $this->get_form($addfileaction,$removefileaction);
234
    }
235
236
    /**
237
     *	Get the form to input an email
238
     *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
239
     *  this->withfile
240
     *  this->param:	Contains more parameteres like email templates info
241
     *
242
     *	@param	string	$addfileaction		Name of action when posting file attachments
243
     *	@param	string	$removefileaction	Name of action when removing file attachments
244
     *	@return string						Form to show
245
     */
246
    function get_form($addfileaction='addfile',$removefileaction='removefile')
0 ignored issues
show
Coding Style introduced by
get_form uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
247
    {
248
        global $conf, $langs, $user, $hookmanager, $form;
249
250
        if (! is_object($form)) $form=new Form($this->db);
251
252
        $langs->load("other");
253
        $langs->load("mails");
254
255
        $hookmanager->initHooks(array('formmail'));
256
257
        $parameters=array(
258
        	'addfileaction' => $addfileaction,
259
        	'removefileaction'=> $removefileaction,
260
            'trackid'=> $this->trackid
261
        );
262
        $reshook=$hookmanager->executeHooks('getFormMail', $parameters, $this);
263
264
        if (!empty($reshook))
265
        {
266
        	return $hookmanager->resPrint;
267
        }
268
        else
269
		{
270
        	$out='';
271
272
        	$disablebademails=1;
273
274
        	// Define list of attached files
275
        	$listofpaths=array();
276
        	$listofnames=array();
277
        	$listofmimes=array();
278
            $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid;   // this->trackid must be defined
279
280
        	if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
281
        	if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
282
        	if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
283
284
       		// Define output language
285
			$outputlangs = $langs;
286
			$newlang = '';
287
			if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $this->param['langsmodels'];
288
			if (! empty($newlang))
289
			{
290
				$outputlangs = new Translate("", $conf);
291
				$outputlangs->setDefaultLang($newlang);
292
				$outputlangs->load('other');
293
			}
294
295
        	// Get message template for $this->param["models"] into c_email_templates
296
			$arraydefaultmessage=array();
297
			if ($this->param['models'] != 'none')
298
			{
299
				$model_id=0;
300
        		if (array_key_exists('models_id',$this->param))
301
        		{
302
	        		$model_id=$this->param["models_id"];
303
        		}
304
	        	$arraydefaultmessage=$this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id);
305
			}
306
        	//var_dump($this->param["models"]);
307
        	//var_dump($model_id);
308
        	//var_dump($arraydefaultmessage);
309
310
        	$out.= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
311
        	if ($this->withform == 1)
312
        	{
313
        		$out.= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
314
        		$out.= '<a id="formmail" name="formmail"></a>';
315
        		$out.= '<input style="display:none" type="submit" id="sendmail" name="sendmail">';
316
        		$out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
317
        		$out.= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
318
        	}
319
        	if (! empty($this->withfrom))
320
        	{
321
        		if (! empty($this->withfromreadonly))
322
        		{
323
        			$out.= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
324
        			$out.= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
325
        		}
326
        	}
327
        	foreach ($this->param as $key=>$value)
328
        	{
329
        		$out.= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
330
        	}
331
332
        	if ($this->param['models'] != 'none')
333
        	{
334
	        	$result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
335
	        	if ($result < 0)
336
	        	{
337
	        		setEventMessages($this->error, $this->errors, 'errors');
338
	        	}
339
	        	$modelmail_array=array();
340
	        	foreach($this->lines_model as $line)
341
	        	{
342
	        		$modelmail_array[$line->id]=$line->label;
343
	        		if ($line->lang) $modelmail_array[$line->id].=' ('.$line->lang.')';
344
	        		if ($line->private) $modelmail_array[$line->id].=' - '.$langs->trans("Private");
345
	        		//if ($line->fk_user != $user->id) $modelmail_array[$line->id].=' - '.$langs->trans("By").' ';
346
	        	}
347
        	}
348
349
        	// Zone to select its email template
350
        	if (count($modelmail_array)>0)
351
        	{
352
	        	$out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
353
        	    $out.= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> '.$this->selectarray('modelmailselected', $modelmail_array, 0, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100');
0 ignored issues
show
Bug introduced by
The variable $modelmail_array does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
354
	        	if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
355
	        	$out.= ' &nbsp; ';
356
	        	$out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
357
	        	$out.= ' &nbsp; ';
358
	        	$out.= '</div>';
359
        	}
360
        	elseif (! empty($this->param['models']) && in_array($this->param['models'], array(
361
        	        'propal_send','order_send','facture_send',
362
        	        'shipping_send','fichinter_send','supplier_proposal_send','order_supplier_send',
363
        	        'invoice_supplier_send','thirdparty','contract','all'
364
           	    )))
365
        	{
366
	        	$out.= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
367
        	    $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.
368
        	    if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')),1);
369
        	    $out.= ' &nbsp; ';
370
        	    $out.= '<input class="button" type="submit" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
371
        	    $out.= ' &nbsp; ';
372
        	    $out.= '</div>';
373
        	}
374
375
376
377
        	$out.= '<table class="border" width="100%">'."\n";
378
379
        	// Substitution array
380
        	if (! empty($this->withsubstit))		// Unset of set ->withsubstit=0 to disable this.
381
        	{
382
        		$out.= '<tr><td colspan="2" align="right">';
383
        		//$out.='<div class="floatright">';
384
        		$help="";
385
        		foreach($this->substit as $key => $val)
386
        		{
387
        			$help.=$key.' -> '.$langs->trans(dol_string_nohtmltag($val)).'<br>';
388
        		}
389
        		if (is_numeric($this->withsubstit)) $out.= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $help, 1, 'help', '', 0, 2, 'substittooltip');	// Old usage
390
        		else $out.= $form->textwithpicto($langs->trans('AvailableVariables'), $help, 1, 'help', '', 0, 2, 'substittooltip');															// New usage
391
        		$out.= "</td></tr>\n";
392
        		//$out.='</div>';
393
        	}
394
395
        	// From
396
        	if (! empty($this->withfrom))
397
        	{
398
        		if (! empty($this->withfromreadonly))
399
        		{
400
        			$out.= '<tr><td class="fieldrequired">'.$langs->trans("MailFrom").'</td><td>';
401
402
                    if (! ($this->fromtype === 'user' && $this->fromid > 0)
403
                        && ! ($this->fromtype === 'company')
404
                        && ! preg_match('/user_aliases/', $this->fromtype)
405
                        && ! preg_match('/global_aliases/', $this->fromtype))
406
                    {
407
                        // Use this->fromname and this->frommail or error if not defined
408
                        $out.= $this->fromname;
409
                        if ($this->frommail)
410
                        {
411
                            $out.= ' &lt;'.$this->frommail.'&gt;';
412
                        }
413
                        else
414
                        {
415
                            if ($this->fromtype)
416
                            {
417
                                $langs->load('errors');
418
                                $out.= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
419
                            }
420
                        }
421
                    } else {
422
                        $liste = array();
423
                        if (empty($user->email))
424
                        {
425
                            $langs->load('errors');
426
                            $liste['user'] = $user->getFullName($langs) . ' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
427
                        }
428
                        else
429
                        {
430
                            $liste['user'] = $user->getFullName($langs) .' &lt;'.$user->email.'&gt;';
431
                        }
432
                        $liste['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM .' &lt;'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'&gt;';
433
                        // Add also email aliases if there is one
434
                        $listaliases=array('user_aliases'=>$user->email_aliases, 'global_aliases'=>$conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES);
435
                        foreach($listaliases as $typealias => $listalias)
436
                        {
437
                            $posalias=0;
438
                            $listaliasarray=explode(',', $listalias);
439
                            foreach ($listaliasarray as $listaliasval)
440
                            {
441
                                $posalias++;
442
                                $listaliasval=trim($listaliasval);
443
                                if ($listaliasval)
444
                                {
445
                                    $listaliasval=preg_replace('/</', '&lt;', $listaliasval);
446
                                    $listaliasval=preg_replace('/>/', '&gt;', $listaliasval);
447
                                    if (! preg_match('/&lt;/', $listaliasval)) $listaliasval='&lt;'.$listaliasval.'&gt;';
448
                                    $liste[$typealias.'_'.$posalias]=$listaliasval;
449
                                }
450
                            }
451
                        }
452
                        $out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', '', 0, '', $disablebademails);
453
                        //$out.= ajax_combobox('fromtype');
454
                    }
455
456
        			$out.= "</td></tr>\n";
457
        		}
458
        		else
459
        		{
460
        			$out.= '<tr><td class="fieldrequired">'.$langs->trans("MailFrom")."</td><td>";
461
        			$out.= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" size="32" value="'.$this->fromname.'" />';
462
        			$out.= '&nbsp; &nbsp; ';
463
        			$out.= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" size="32" value="'.$this->frommail.'" />&gt;';
464
        			$out.= "</td></tr>\n";
465
        		}
466
        	}
467
468
        	// withoptiononeemailperrecipient
469
        	if (! empty($this->withoptiononeemailperrecipient))
470
        	{
471
        		$out.= '<tr><td class="fieldrequired" width="180">';
472
        		$out.= $langs->trans("GroupEmails");
473
        		$out.= '</td><td>';
474
        		$out.=' <input type="checkbox" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0?' checked="checked"':'').'> ';
475
        		$out.= $langs->trans("OneEmailPerRecipient").' - ';
476
        		$out.= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
477
        		$out.= '</td></tr>';
478
479
        	}
480
481
        	// To
482
        	if (! empty($this->withto) || is_array($this->withto))
483
        	{
484
        		$out.= '<tr><td class="fieldrequired" width="180">';
485
        		if ($this->withtofree) $out.= $form->textwithpicto($langs->trans("MailTo"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
486
        		else $out.= $langs->trans("MailTo");
487
        		$out.= '</td><td>';
488
        		if ($this->withtoreadonly)
489
        		{
490
        			if (! empty($this->toname) && ! empty($this->tomail))
491
        			{
492
        				$out.= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
493
        				$out.= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
494
        				if ($this->totype == 'thirdparty')
495
        				{
496
        					$soc=new Societe($this->db);
497
        					$soc->fetch($this->toid);
498
        					$out.= $soc->getNomUrl(1);
499
        				}
500
        				else if ($this->totype == 'contact')
501
        				{
502
        					$contact=new Contact($this->db);
503
        					$contact->fetch($this->toid);
504
        					$out.= $contact->getNomUrl(1);
505
        				}
506
        				else
507
        				{
508
        					$out.= $this->toname;
509
        				}
510
        				$out.= ' &lt;'.$this->tomail.'&gt;';
511
        				if ($this->withtofree)
512
        				{
513
        					$out.= '<br>'.$langs->trans("and").' <input size="'.(is_array($this->withto)?"30":"60").'" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
514
        				}
515
        			}
516
        			else
517
        			{
518
        				// Note withto may be a text like 'AllRecipientSelected'
519
        				$out.= (! is_array($this->withto) && ! is_numeric($this->withto))?$this->withto:"";
520
        			}
521
        		}
522
        		else
523
        		{
524
        			if (! empty($this->withtofree))
525
        			{
526
        				$out.= '<input size="'.(is_array($this->withto)?"30":"60").'" id="sendto" name="sendto" value="'.(! is_array($this->withto) && ! is_numeric($this->withto)? (isset($_REQUEST["sendto"])?$_REQUEST["sendto"]:$this->withto) :"").'" />';
527
        			}
528
        			if (! empty($this->withto) && is_array($this->withto))
529
        			{
530
        				if (! empty($this->withtofree)) $out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
531
        			    // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
532
        				$tmparray = $this->withto;
533
        				foreach($tmparray as $key => $val)
534
        				{
535
        				    $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
536
        				}
537
        				$withtoselected=GETPOST("receiver",'none');     // Array of selected value
538
        				if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action','aZ09') == 'presend')
539
        				{
540
        				    $withtoselected = array_keys($tmparray);
541
        				}
542
        				$out.= $form->multiselectarray("receiver", $tmparray, $withtoselected, null, null, 'inline-block minwidth500', null, "");
543
        			}
544
        		}
545
        		$out.= "</td></tr>\n";
546
        	}
547
548
        	// CC
549
        	if (! empty($this->withtocc) || is_array($this->withtocc))
550
        	{
551
        		$out.= '<tr><td width="180">';
552
        		$out.= $form->textwithpicto($langs->trans("MailCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
553
        		$out.= '</td><td>';
554
        		if ($this->withtoccreadonly)
555
        		{
556
        			$out.= (! is_array($this->withtocc) && ! is_numeric($this->withtocc))?$this->withtocc:"";
557
        		}
558
        		else
559
        		{
560
        			$out.= '<input size="'.(is_array($this->withtocc)?"30":"60").'" 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"]:"") ).'" />';
561
        			if (! empty($this->withtocc) && is_array($this->withtocc))
562
        			{
563
        				$out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
564
        				// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
565
        				$tmparray = $this->withtocc;
566
        				foreach($tmparray as $key => $val)
567
        				{
568
        				    $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
569
        				}
570
        				$withtoccselected=GETPOST("receivercc");     // Array of selected value
571
        				$out.= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, null, null, 'inline-block minwidth500',null, "");
572
        			}
573
        		}
574
        		$out.= "</td></tr>\n";
575
        	}
576
577
        	// CCC
578
        	if (! empty($this->withtoccc) || is_array($this->withtoccc))
579
        	{
580
        		$out.= '<tr><td width="180">';
581
        		$out.= $form->textwithpicto($langs->trans("MailCCC"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
582
        		$out.= '</td><td>';
583
        		if (! empty($this->withtocccreadonly))
584
        		{
585
        			$out.= (! is_array($this->withtoccc) && ! is_numeric($this->withtoccc))?$this->withtoccc:"";
586
        		}
587
        		else
588
        		{
589
        			$out.= '<input size="'.(is_array($this->withtoccc)?"30":"60").'" 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"]:"") ).'" />';
590
        			if (! empty($this->withtoccc) && is_array($this->withtoccc))
591
        			{
592
        				$out.= " ".$langs->trans("and")."/".$langs->trans("or")." ";
593
        				// multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time
594
        				$tmparray = $this->withtoccc;
595
        				foreach($tmparray as $key => $val)
596
        				{
597
        				    $tmparray[$key]=dol_htmlentities($tmparray[$key], null, 'UTF-8', true);
598
        				}
599
        				$withtocccselected=GETPOST("receiverccc");     // Array of selected value
600
        				$out.= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, null, null, null,null, "90%");
601
        			}
602
        		}
603
604
        		$showinfobcc='';
605
        		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;
606
				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;
607
        		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;
608
        		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;
609
        		if ($showinfobcc) $out.=' + '.$showinfobcc;
610
        		$out.= "</td></tr>\n";
611
        	}
612
613
        	// Replyto
614
        	if (! empty($this->withreplyto))
615
        	{
616
        		if ($this->withreplytoreadonly)
617
        		{
618
        			$out.= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
619
        			$out.= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
620
        			$out.= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail?(" &lt;".$this->replytomail."&gt;"):"");
621
        			$out.= "</td></tr>\n";
622
        		}
623
        	}
624
625
        	// Errorsto
626
        	if (! empty($this->witherrorsto))
627
        	{
628
        		//if (! $this->errorstomail) $this->errorstomail=$this->frommail;
629
        		$errorstomail = (! empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : $this->errorstomail);
630
        		if ($this->witherrorstoreadonly)
631
        		{
632
        			$out.= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
633
        			$out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
634
        			$out.= $errorstomail;
635
        			$out.= "</td></tr>\n";
636
        		}
637
        		else
638
        		{
639
        			$out.= '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
640
        			$out.= '<input size="30" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
641
        			$out.= "</td></tr>\n";
642
        		}
643
        	}
644
645
        	// Ask delivery receipt
646
        	if (! empty($this->withdeliveryreceipt))
647
        	{
648
        		$out.= '<tr><td width="180">'.$langs->trans("DeliveryReceipt").'</td><td>';
649
650
        		if (! empty($this->withdeliveryreceiptreadonly))
651
        		{
652
        			$out.= yn($this->withdeliveryreceipt);
653
        		}
654
        		else
655
        		{
656
        			$defaultvaluefordeliveryreceipt=0;
657
        			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_PROPAL) && ! empty($this->param['models']) && $this->param['models'] == 'propal_send') $defaultvaluefordeliveryreceipt=1;
658
					if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL) && ! empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') $defaultvaluefordeliveryreceipt=1;
659
        			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_ORDER) && ! empty($this->param['models']) && $this->param['models'] == 'order_send') $defaultvaluefordeliveryreceipt=1;
660
        			if (! empty($conf->global->MAIL_FORCE_DELIVERY_RECEIPT_INVOICE) && ! empty($this->param['models']) && $this->param['models'] == 'facture_send') $defaultvaluefordeliveryreceipt=1;
661
        			$out.= $form->selectyesno('deliveryreceipt', (isset($_POST["deliveryreceipt"])?$_POST["deliveryreceipt"]:$defaultvaluefordeliveryreceipt), 1);
662
        		}
663
664
        		$out.= "</td></tr>\n";
665
        	}
666
667
        	// Topic
668
        	if (! empty($this->withtopic))
669
        	{
670
        		$defaulttopic=GETPOST('subject','none');
671
				if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1')
672
				{
673
        			if (count($arraydefaultmessage) > 0 && $arraydefaultmessage['topic']) $defaulttopic=$arraydefaultmessage['topic'];
674
        			elseif (! is_numeric($this->withtopic))	 $defaulttopic=$this->withtopic;
675
				}
676
677
        		$defaulttopic=make_substitutions($defaulttopic,$this->substit);
678
679
        		$out.= '<tr>';
680
        		$out.= '<td class="fieldrequired" width="180">'.$langs->trans("MailTopic").'</td>';
681
        		$out.= '<td>';
682
        		if ($this->withtopicreadonly)
683
        		{
684
        			$out.= $defaulttopic;
685
        			$out.= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" />';
686
        		}
687
        		else
688
        		{
689
        			$out.= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'. ((isset($_POST["subject"]) && ! $_POST['modelselected'])?$_POST["subject"]:($defaulttopic?$defaulttopic:'')) .'" />';
690
        		}
691
        		$out.= "</td></tr>\n";
692
        	}
693
694
        	// Attached files
695
        	if (! empty($this->withfile))
696
        	{
697
        		$out.= '<tr>';
698
        		$out.= '<td width="180">'.$langs->trans("MailFile").'</td>';
699
700
        		$out.= '<td>';
701
        		if (! empty($this->withmaindocfile))
702
        		{
703
        			if ($this->withmaindocfile == 1)
704
        			{
705
        				$out.='<input type="checkbox" name="addmaindocfile" value="1" />';
706
        			}
707
        			if ($this->withmaindocfile == -1)
708
        			{
709
        				$out.='<input type="checkbox" name="addmaindocfile" checked="checked" />';
710
        			}
711
        			$out.=' '.$langs->trans("JoinMainDoc").'.<br>';
712
        		}
713
714
        		if (is_numeric($this->withfile))
715
        		{
716
					// TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript
717
	        		$out.= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
718
	        		$out.= '<script type="text/javascript" language="javascript">';
719
	        		$out.= 'jQuery(document).ready(function () {';
720
	        		$out.= '    jQuery(".removedfile").click(function() {';
721
	        		$out.= '        jQuery(".removedfilehidden").val(jQuery(this).val());';
722
	        		$out.= '    });';
723
	        		$out.= '})';
724
	        		$out.= '</script>'."\n";
725
	        		if (count($listofpaths))
726
	        		{
727
	        			foreach($listofpaths as $key => $val)
728
	        			{
729
	        				$out.= '<div id="attachfile_'.$key.'">';
730
	        				$out.= img_mime($listofnames[$key]).' '.$listofnames[$key];
731
	        				if (! $this->withfilereadonly)
732
	        				{
733
	        					$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.'" />';
734
	        					//$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).' id="removedfile_'.$key.'">'.img_delete($langs->trans("Delete").'</a>';
735
	        				}
736
	        				$out.= '<br></div>';
737
	        			}
738
	        		}
739
	        		else if (empty($this->withmaindocfile))		// Do not show message if we asked to show the checkbox
740
	        		{
741
	        			$out.= $langs->trans("NoAttachedFiles").'<br>';
742
	        		}
743
	        		if ($this->withfile == 2)	// Can add other files
744
	        		{
745
	        			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 />';
746
						else $out.= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
747
	        			$out.= ' ';
748
	        			$out.= '<input class="button" type="submit" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
749
	        		}
750
        		}
751
        		else
752
        		{
753
        			$out.=$this->withfile;
754
        		}
755
756
        		$out.= "</td></tr>\n";
757
        	}
758
759
        	// Message
760
        	if (! empty($this->withbody))
761
        	{
762
        		$defaultmessage=GETPOST('message','none');
763
				if (! GETPOST('modelselected','alpha') || GETPOST('modelmailselected') != '-1')
764
				{
765
					if (count($arraydefaultmessage) > 0 && $arraydefaultmessage['content']) $defaultmessage=$arraydefaultmessage['content'];
766
       				elseif (! is_numeric($this->withbody))	$defaultmessage=$this->withbody;
767
				}
768
769
        		// Complete substitution array
770
        		$paymenturl='';
771
        		if (! empty($conf->global->PAYMENT_ADD_PAYMENT_URL)		// Option to enable to add online link into __PERSONALIZED__
772
        			|| (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_ADD_PAYMENT_URL))
773
        		)
774
        		{
775
        			if (empty($this->substit['__REF__']))
776
        			{
777
        				//$paymenturl='LinkToPayOnlineNotAvailableInThisContext';
778
        				$paymenturl='';
779
        			}
780
        			else
781
        			{
782
	        			// Set the online payment message and url link into __PERSONALIZED__ key
783
	        			require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
784
	        			$langs->load('paypal');
785
	        			$typeforonlinepayment='free';
786
	        			if ($this->param["models"]=='order_send')   $typeforonlinepayment='order';		// TODO use detection on something else than template
787
	        			if ($this->param["models"]=='facture_send') $typeforonlinepayment='invoice';	// TODO use detection on something else than template
788
	       				$url=getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
789
	       				//$paymenturl=str_replace('\n',"\n",$langs->transnoentitiesnoconv("PredefinedMailContentLink",$url));
790
	       				$paymenturl=$url;
791
        			}
792
        		}
793
        		$this->substit['__PERSONALIZED__']=$paymenturl;			// deprecated
794
        		$this->substit['__ONLINE_PAYMENT_URL__']=$paymenturl;
795
796
                //Add lines substitution key from each line
797
                $lines = '';
798
                $defaultlines = $arraydefaultmessage['content_lines'];
799
                if (isset($defaultlines))
800
                {
801
                    foreach ($this->substit_lines as $substit_line)
802
                    {
803
                        $lines .= make_substitutions($defaultlines,$substit_line)."\n";
804
                    }
805
                }
806
                $this->substit['__LINES__']=$lines;
807
808
				$defaultmessage=str_replace('\n',"\n",$defaultmessage);
809
810
				// Deal with format differences between message and signature (text / HTML)
811
				if(dol_textishtml($defaultmessage) && !dol_textishtml($this->substit['__SIGNATURE__'])) {
812
					$this->substit['__SIGNATURE__'] = dol_nl2br($this->substit['__SIGNATURE__']);
813
				} else if(!dol_textishtml($defaultmessage) && dol_textishtml($this->substit['__SIGNATURE__'])) {
814
					$defaultmessage = dol_nl2br($defaultmessage);
815
				}
816
817
818
        		if (isset($_POST["message"]) &&  ! $_POST['modelselected']) $defaultmessage=$_POST["message"];
819
				else
820
				{
821
					$defaultmessage=make_substitutions($defaultmessage,$this->substit);
822
					// Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
823
					$defaultmessage=preg_replace("/^(<br>)+/","",$defaultmessage);
824
					$defaultmessage=preg_replace("/^\n+/","",$defaultmessage);
825
				}
826
827
        		$out.= '<tr>';
828
        		$out.= '<td width="180" valign="top">'.$langs->trans("MailText").'</td>';
829
        		$out.= '<td>';
830
        		if ($this->withbodyreadonly)
831
        		{
832
        			$out.= nl2br($defaultmessage);
833
        			$out.= '<input type="hidden" id="message" name="message" value="'.$defaultmessage.'" />';
834
        		}
835
        		else
836
        		{
837
        			if (! isset($this->ckeditortoolbar)) $this->ckeditortoolbar = 'dolibarr_notes';
838
839
        			// Editor wysiwyg
840
        			require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
841
        			if ($this->withfckeditor == -1)
842
        			{
843
        				if (! empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $this->withfckeditor=1;
844
						else $this->withfckeditor=0;
845
        			}
846
847
        			$doleditor=new DolEditor('message',$defaultmessage,'',280,$this->ckeditortoolbar,'In',true,true,$this->withfckeditor,8,'95%');
848
        			$out.= $doleditor->Create(1);
849
        		}
850
        		$out.= "</td></tr>\n";
851
        	}
852
853
        	$out.= '</table>'."\n";
854
855
        	if ($this->withform == 1 || $this->withform == -1)
856
        	{
857
        		$out.= '<br><div class="center">';
858
        		$out.= '<input class="button" type="submit" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
859
        		// Add a javascript test to avoid to forget to submit file before sending email
860
        		if ($this->withfile == 2 && $conf->use_javascript_ajax)
861
        		{
862
        			$out.= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
863
        		}
864
        		$out.= ' />';
865
        		if ($this->withcancel)
866
        		{
867
        			$out.= ' &nbsp; &nbsp; ';
868
        			$out.= '<input class="button" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
869
        		}
870
        		$out.= '</div>'."\n";
871
        	}
872
873
        	if ($this->withform == 1) $out.= '</form>'."\n";
874
875
        	// Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
876
        	if (! empty($conf->global->MAIN_MAILFORM_DISABLE_ENTERKEY))
877
        	{
878
	        	$out.= '<script type="text/javascript" language="javascript">';
879
		        $out.= 'jQuery(document).ready(function () {';
880
				$out.= '	$(document).on("keypress", \'#mailform\', function (e) {		/* Note this is called at every key pressed ! */
881
	    						var code = e.keyCode || e.which;
882
	    						if (code == 13) {
883
	        						e.preventDefault();
884
	        						return false;
885
	    						}
886
							});';
887
				$out.='		})';
888
				$out.= '</script>';
889
        	}
890
891
        	$out.= "<!-- End form mail -->\n";
892
893
        	return $out;
894
        }
895
    }
896
897
898
899
	/**
900
	 *      Return templates of email with type = $type_template or type = 'all'
901
	 *      This search into table c_email_templates.
902
	 *
903
	 * 		@param	DoliDB		$db				Database handler
904
	 * 		@param	string		$type_template	Get message for type=$type_template, type='all' also included.
905
	 *      @param	string		$user			Use template public or limited to this user
906
	 *      @param	Translate	$outputlangs	Output lang object
907
	 *      @param	int			$id				Id template to find
908
	 *      @param  int         $active         1=Only active template, 0=Only disabled, -1=All
909
	 *      @return array						array('topic'=>,'content'=>,..)
910
	 */
911
	private function getEMailTemplate($db, $type_template, $user, $outputlangs, $id=0, $active=1)
912
	{
913
		$ret=array();
914
915
		$sql = "SELECT label, topic, content, content_lines, lang";
916
		$sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
917
		$sql.= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')";
918
		$sql.= " AND entity IN (".getEntity('c_email_templates', 0).")";
919
		$sql.= " AND (private = 0 OR fk_user = ".$user->id.")";				// Get all public or private owned
920
		if ($active >= 0) $sql.=" AND active = ".$active;
921
		if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
922
		if (!empty($id)) $sql.= " AND rowid=".$id;
923
		$sql.= $db->order("position,lang,label","ASC");
924
		//print $sql;
925
926
		$resql = $db->query($sql);
927
		if ($resql)
928
		{
929
			$obj = $db->fetch_object($resql);	// Get first found
930
			if ($obj)
931
			{
932
				$ret['label']=$obj->label;
933
				$ret['topic']=$obj->topic;
934
				$ret['content']=$obj->content;
935
				$ret['content_lines']=$obj->content_lines;
936
				$ret['lang']=$obj->lang;
937
			}
938
			else								// If there is no template at all
939
			{
940
				$defaultmessage='';
941
				if     ($type_template=='facture_send')	            { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoice"); }
942
	        	elseif ($type_template=='facture_relance')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendInvoiceReminder"); }
943
	        	elseif ($type_template=='propal_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendProposal"); }
944
	        	elseif ($type_template=='supplier_proposal_send')	{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal"); }
945
	        	elseif ($type_template=='order_send')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendOrder"); }
946
	        	elseif ($type_template=='order_supplier_send')		{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder"); }
947
	        	elseif ($type_template=='invoice_supplier_send')	{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice"); }
948
	        	elseif ($type_template=='shipping_send')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendShipping"); }
949
	        	elseif ($type_template=='fichinter_send')			{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentSendFichInter"); }
950
	        	elseif ($type_template=='thirdparty')				{ $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentThirdparty"); }
951
	        	elseif ($type_template=='user')				        { $defaultmessage=$outputlangs->transnoentities("PredefinedMailContentUser"); }
952
953
	        	$ret['label']='default';
954
	        	$ret['topic']='';
955
	        	$ret['content']=$defaultmessage;
956
				$ret['content_lines']='';
957
	        	$ret['lang']=$outputlangs->defaultlang;
958
			}
959
960
			$db->free($resql);
961
			return $ret;
962
		}
963
		else
964
		{
965
			dol_print_error($db);
966
			return -1;
967
		}
968
	}
969
970
	/**
971
	 *      Find if template exists
972
	 *      Search into table c_email_templates
973
	 *
974
	 * 		@param	string		$type_template	Get message for key module
975
	 *      @param	string		$user			Use template public or limited to this user
976
	 *      @param	Translate	$outputlangs	Output lang object
977
	 *      @return	int		<0 if KO,
978
	 */
979
	public function isEMailTemplate($type_template, $user, $outputlangs)
980
	{
981
		$ret=array();
982
983
		$sql = "SELECT label, topic, content, lang";
984
		$sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
985
		$sql.= " WHERE type_template='".$this->db->escape($type_template)."'";
986
		$sql.= " AND entity IN (".getEntity('c_email_templates', 0).")";
987
		$sql.= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".$user->id.")";
988
		if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";
989
		$sql.= $this->db->order("lang,label","ASC");
990
		//print $sql;
991
992
		$resql = $this->db->query($sql);
993
		if ($resql)
994
		{
995
			$num= $this->db->num_rows($resql);
996
			$this->db->free($resql);
997
			return $num;
998
		}
999
		else
1000
		{
1001
			$this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1002
			return -1;
1003
		}
1004
	}
1005
1006
	/**
1007
	 *      Find if template exists and are available for current user, then set them into $this->lines_module.
1008
	 *      Search into table c_email_templates
1009
	 *
1010
	 * 		@param	string		$type_template	Get message for key module
1011
	 *      @param	string		$user			Use template public or limited to this user
1012
	 *      @param	Translate	$outputlangs	Output lang object
1013
	 *      @param  int         $active         1=Only active template, 0=Only disabled, -1=All
1014
	 *      @return	int		                    <0 if KO, nb of records found if OK
1015
	 */
1016
	public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active=1)
1017
	{
1018
		$ret=array();
1019
1020
		$sql = "SELECT rowid, label, topic, content, content_lines, lang, fk_user, private, position";
1021
		$sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates';
1022
		$sql.= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
1023
		$sql.= " AND entity IN (".getEntity('c_email_templates', 0).")";
1024
		$sql.= " AND (private = 0 OR fk_user = ".$user->id.")";		// See all public templates or templates I own.
1025
		if ($active >= 0) $sql.=" AND active = ".$active;
1026
		//if (is_object($outputlangs)) $sql.= " AND (lang = '".$outputlangs->defaultlang."' OR lang IS NULL OR lang = '')";	// Return all languages
1027
		$sql.= $this->db->order("position,lang,label","ASC");
1028
		//print $sql;
1029
1030
		$resql = $this->db->query($sql);
1031
		if ($resql)
1032
		{
1033
			$num=$this->db->num_rows($resql);
1034
			$this->lines_model=array();
1035
			while ($obj = $this->db->fetch_object($resql))
1036
			{
1037
				$line = new ModelMail();
1038
				$line->id=$obj->rowid;
1039
				$line->label=$obj->label;
1040
				$line->lang=$obj->lang;
1041
				$line->fk_user=$obj->fk_user;
1042
				$line->private=$obj->private;
1043
				$line->position=$obj->position;
1044
				$line->topic=$obj->topic;
1045
				$line->content=$obj->content;
1046
				$line->content_lines=$obj->content_lines;
1047
				$this->lines_model[]=$line;
1048
			}
1049
			$this->db->free($resql);
1050
			return $num;
1051
		}
1052
		else
1053
		{
1054
			$this->error=get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
1055
			return -1;
1056
		}
1057
	}
1058
1059
1060
1061
	/**
1062
	 * Set substit array from object. This is call when suggesting the email template into forms before sending email.
1063
	 *
1064
	 * @param	CommonObject	$object		   Object to use
1065
	 * @param   Translate  		$outputlangs   Object lang
1066
	 * @return	void
1067
	 * @see getCommonSubstitutionArray
1068
	 */
1069
	function setSubstitFromObject($object, $outputlangs=null)
1070
	{
1071
		global $conf, $user;
1072
1073
		$parameters=array('mode'=>$mode);
0 ignored issues
show
Bug introduced by
The variable $mode does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1074
		$tmparray=getCommonSubstitutionArray($outputlangs, 0, null, $object);
0 ignored issues
show
Bug introduced by
It seems like $outputlangs defined by parameter $outputlangs on line 1069 can be null; however, getCommonSubstitutionArray() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
1075
		complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
0 ignored issues
show
Bug introduced by
It seems like $outputlangs defined by parameter $outputlangs on line 1069 can be null; however, complete_substitutions_array() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
1076
1077
		$this->substit=$tmparray;
1078
1079
        // Fill substit_lines with each object lines content
1080
        if (is_array($object->lines))
1081
        {
1082
            foreach ($object->lines as $line)
1083
            {
1084
                $substit_line = array(
1085
                    '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
1086
                    '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
1087
                    '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
1088
                    '__LABEL__' => isset($line->label) ? $line->label : '',
1089
                    '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
1090
                    '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', 0, $outputlangs),
0 ignored issues
show
Bug introduced by
It seems like $outputlangs defined by parameter $outputlangs on line 1069 can be null; however, dol_print_date() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
1091
                    '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', 0, $outputlangs),
0 ignored issues
show
Bug introduced by
It seems like $outputlangs defined by parameter $outputlangs on line 1069 can be null; however, dol_print_date() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
1092
                    '__QUANTITY__' => $line->qty,
1093
                    '__SUBPRICE__' => price($line->subprice),
1094
                    '__AMOUNT__' => price($line->total_ttc),
1095
                    '__AMOUNT_EXCL_TAX__' => price($line->total_ht),
1096
                    //'__PRODUCT_EXTRAFIELD_FIELD__' Done dinamically just after
1097
                );
1098
1099
                // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
1100
                if (!empty($line->fk_product))
1101
                {
1102
                    $extrafields = new ExtraFields($this->db);
1103
                    $extralabels = $extrafields->fetch_name_optionals_label('product', true);
1104
                    $product = new Product($this->db);
1105
                    $product->fetch($line->fk_product, '', '', 1);
1106
                    $product->fetch_optionals($product->id, $extralabels);
1107
                    foreach ($extrafields->attribute_label as $key => $label) {
1108
                        $substit_line['__PRODUCT_EXTRAFIELD_' . strtoupper($key) . '__'] = $product->array_options['options_' . $key];
1109
                    }
1110
                }
1111
                $this->substit_lines[] = $substit_line;
1112
            }
1113
        }
1114
	}
1115
1116
	/**
1117
	 * Get list of substitution keys available for emails. This is used for tooltips help.
1118
	 * This include the complete_substitutions_array.
1119
	 *
1120
	 * @param	string	$mode		'formemail', 'formemailwithlines', 'formemailforlines', 'emailing', ...
1121
	 * @param	Object	$object		Object if applicable
1122
	 * @return	array               Array of substitution values for emails.
1123
	 */
1124
	static function getAvailableSubstitKey($mode='formemail', $object=null)
1125
	{
1126
		global $conf, $langs;
1127
1128
		if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines')
1129
		{
1130
			$parameters=array('mode'=>$mode);
1131
			$tmparray=getCommonSubstitutionArray($langs, 2, null, $object);			// Note: On email templated edition, this is null because it is related to all type of objects
1132
			complete_substitutions_array($tmparray, $langs, null, $parameters);
1133
1134
			if ($mode == 'formwithlines')
1135
			{
1136
			    $tmparray['__LINES__'] = '__LINES__';      // Will be set by the get_form function
1137
			}
1138
			if ($mode == 'formforlines')
1139
			{
1140
			    $tmparray['__QUANTITY__'] = '__QUANTITY__';   // Will be set by the get_form function
1141
			}
1142
		}
1143
1144
		if ($mode == 'emailing')
1145
		{
1146
			$parameters=array('mode'=>$mode);
1147
			$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
1148
			complete_substitutions_array($tmparray, $langs, null, $parameters);
1149
1150
			// For mass emailing, we have different keys
1151
			$tmparray['__ID__'] = 'IdRecord';
1152
			$tmparray['__EMAIL__'] = 'EMailRecipient';
1153
			$tmparray['__LASTNAME__'] = 'Lastname';
1154
			$tmparray['__FIRSTNAME__'] = 'Firstname';
1155
			$tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
1156
			$tmparray['__OTHER1__'] = 'Other1';
1157
			$tmparray['__OTHER2__'] = 'Other2';
1158
			$tmparray['__OTHER3__'] = 'Other3';
1159
			$tmparray['__OTHER4__'] = 'Other4';
1160
			$tmparray['__OTHER5__'] = 'Other5';
1161
			$tmparray['__SIGNATURE__'] = 'TagSignature';
1162
			$tmparray['__CHECK_READ__'] = 'TagCheckMail';
1163
			$tmparray['__UNSUBSCRIBE__'] = 'TagUnsubscribe';
1164
				//,'__PERSONALIZED__' => 'Personalized'	// Hidden because not used yet in mass emailing
1165
1166
			$onlinepaymentenabled = 0;
1167
			if (! empty($conf->paypal->enabled)) $onlinepaymentenabled++;
1168
			if (! empty($conf->paybox->enabled)) $onlinepaymentenabled++;
1169
			if (! empty($conf->stripe->enabled)) $onlinepaymentenabled++;
1170
			if ($onlinepaymentenabled && ! empty($conf->global->PAYMENT_SECURITY_TOKEN))
1171
			{
1172
				$tmparray['__SECUREKEYPAYMENT__']=$conf->global->PAYMENT_SECURITY_TOKEN;
1173
				if (! empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE))
1174
				{
1175
					if ($conf->adherent->enabled) $tmparray['__SECUREKEYPAYMENT_MEMBER__']='SecureKeyPAYMENTUniquePerMember';
1176
					if ($conf->facture->enabled)  $tmparray['__SECUREKEYPAYMENT_INVOICE__']='SecureKeyPAYMENTUniquePerInvoice';
1177
					if ($conf->commande->enabled) $tmparray['__SECUREKEYPAYMENT_ORDER__']='SecureKeyPAYMENTUniquePerOrder';
1178
					if ($conf->contrat->enabled)  $tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__']='SecureKeyPAYMENTUniquePerContractLine';
1179
				}
1180
			}
1181
			else
1182
			{
1183
				/* No need to show into tooltip help, option is not enabled
1184
				$vars['__SECUREKEYPAYMENT__']='';
1185
				$vars['__SECUREKEYPAYMENT_MEMBER__']='';
1186
				$vars['__SECUREKEYPAYMENT_INVOICE__']='';
1187
				$vars['__SECUREKEYPAYMENT_ORDER__']='';
1188
				$vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
1189
				*/
1190
			}
1191
		}
1192
1193
		$tmparray['__(AnyTranslationKey)__']="Translation";
0 ignored issues
show
Bug introduced by
The variable $tmparray does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1194
1195
		foreach($tmparray as $key => $val)
1196
		{
1197
			if (empty($val)) $tmparray[$key]=$key;
1198
		}
1199
1200
		return $tmparray;
1201
	}
1202
1203
}
1204
1205
1206
/**
1207
 * ModelMail
1208
 */
1209
class ModelMail
1210
{
1211
	public $id;
1212
	public $label;
1213
	public $topic;
1214
	public $content;
1215
	public $content_lines;
1216
	public $lang;
1217
}
1218