Completed
Branch develop (24c267)
by
unknown
24:04
created

Form::selectUnits()   C

Complexity

Conditions 8
Paths 3

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 16
nc 3
nop 3
dl 0
loc 31
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/* Copyright (c) 2002-2007  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2004-2012  Laurent Destailleur     <[email protected]>
4
 * Copyright (C) 2004       Benoit Mortier          <[email protected]>
5
 * Copyright (C) 2004       Sebastien Di Cintio     <[email protected]>
6
 * Copyright (C) 2004       Eric Seigne             <[email protected]>
7
 * Copyright (C) 2005-2014  Regis Houssin           <[email protected]>
8
 * Copyright (C) 2006       Andre Cianfarani        <[email protected]>
9
 * Copyright (C) 2006       Marc Barilley/Ocebo     <[email protected]>
10
 * Copyright (C) 2007       Franky Van Liedekerke   <[email protected]>
11
 * Copyright (C) 2007       Patrick Raguin          <[email protected]>
12
 * Copyright (C) 2010       Juanjo Menent           <[email protected]>
13
 * Copyright (C) 2010-2014  Philippe Grand          <[email protected]>
14
 * Copyright (C) 2011       Herve Prot              <[email protected]>
15
 * Copyright (C) 2012-2016  Marcos García           <[email protected]>
16
 * Copyright (C) 2012       Cedric Salvador         <[email protected]>
17
 * Copyright (C) 2012-2015  Raphaël Doursenaud      <[email protected]>
18
 * Copyright (C) 2014       Alexandre Spangaro      <[email protected]>
19
 *
20
 * This program is free software; you can redistribute it and/or modify
21
 * it under the terms of the GNU General Public License as published by
22
 * the Free Software Foundation; either version 3 of the License, or
23
 * (at your option) any later version.
24
 *
25
 * This program is distributed in the hope that it will be useful,
26
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
 * GNU General Public License for more details.
29
 *
30
 * You should have received a copy of the GNU General Public License
31
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32
 */
33
34
/**
35
 *	\file       htdocs/core/class/html.form.class.php
36
 *  \ingroup    core
37
 *	\brief      File of class with all html predefined components
38
 */
39
40
41
/**
42
 *	Class to manage generation of HTML components
43
 *	Only common components must be here.
44
 *
45
 *  TODO Merge all function load_cache_* and loadCache* (except load_cache_vatrates) into one generic function loadCacheTable
46
 */
47
class Form
48
{
49
    var $db;
50
    var $error;
51
    var $num;
52
53
    // Cache arrays
54
    var $cache_types_paiements=array();
55
    var $cache_conditions_paiements=array();
56
    var $cache_availability=array();
57
    var $cache_demand_reason=array();
58
    var $cache_types_fees=array();
59
    var $cache_vatrates=array();
60
61
62
    /**
63
     * Constructor
64
     *
65
     * @param		DoliDB		$db      Database handler
66
     */
67
    public function __construct($db)
68
    {
69
        $this->db = $db;
70
    }
71
72
    /**
73
     * Output key field for an editable field
74
     *
75
     * @param   string	$text			Text of label or key to translate
76
     * @param   string	$htmlname		Name of select field ('edit' prefix will be added)
77
     * @param   string	$preselected    Value to show/edit (not used in this function)
78
     * @param	object	$object			Object
79
     * @param	boolean	$perm			Permission to allow button to edit parameter. Set it to 0 to have a not edited field.
80
     * @param	string	$typeofdata		Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'ckeditor:dolibarr_zzz:width:height:savemethod:1:rows:cols', 'select;xxx[:class]'...)
81
     * @param	string	$moreparam		More param to add on a href URL.
82
     * @param   int     $fieldrequired  1 if we want to show field as mandatory using the "fieldrequired" CSS.
83
     * @param   int     $notabletag     1=Do not output table tags but output a ':', 2=Do not output table tags and no ':', 3=Do not output table tags but output a ' '
84
     * @return	string					HTML edit field
85
     */
86
    function editfieldkey($text, $htmlname, $preselected, $object, $perm, $typeofdata='string', $moreparam='', $fieldrequired=0, $notabletag=0)
87
    {
88
        global $conf,$langs;
89
90
        $ret='';
91
92
        // TODO change for compatibility
93
        if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;/',$typeofdata))
94
        {
95
            if (! empty($perm))
96
            {
97
                $tmp=explode(':',$typeofdata);
98
                $ret.= '<div class="editkey_'.$tmp[0].(! empty($tmp[1]) ? ' '.$tmp[1] : '').'" id="'.$htmlname.'">';
99
	            if ($fieldrequired) $ret.='<span class="fieldrequired">';
100
                $ret.= $langs->trans($text);
101
	            if ($fieldrequired) $ret.='</span>';
102
                $ret.= '</div>'."\n";
103
            }
104
            else
105
            {
106
	            if ($fieldrequired) $ret.='<span class="fieldrequired">';
107
                $ret.= $langs->trans($text);
108
	            if ($fieldrequired) $ret.='</span>';
109
            }
110
        }
111
        else
112
		{
113
            if (empty($notabletag) && GETPOST('action') != 'edit'.$htmlname && $perm) $ret.='<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
114
	        if ($fieldrequired) $ret.='<span class="fieldrequired">';
115
            $ret.=$langs->trans($text);
116
	        if ($fieldrequired) $ret.='</span>';
117
	        if (! empty($notabletag)) $ret.=' ';
118
            if (empty($notabletag) && GETPOST('action') != 'edit'.$htmlname && $perm) $ret.='</td>';
119
            if (empty($notabletag) && GETPOST('action') != 'edit'.$htmlname && $perm) $ret.='<td align="right">';
120
            if ($htmlname && GETPOST('action') != 'edit'.$htmlname && $perm) $ret.='<a href="'.$_SERVER["PHP_SELF"].'?action=edit'.$htmlname.'&amp;id='.$object->id.$moreparam.'">'.img_edit($langs->trans('Edit'), ($notabletag ? 0 : 1)).'</a>';
121
	        if (! empty($notabletag) && $notabletag == 1) $ret.=' : ';
122
	        if (! empty($notabletag) && $notabletag == 3) $ret.=' ';
123
            if (empty($notabletag) && GETPOST('action') != 'edit'.$htmlname && $perm) $ret.='</td>';
124
            if (empty($notabletag) && GETPOST('action') != 'edit'.$htmlname && $perm) $ret.='</tr></table>';
125
        }
126
127
        return $ret;
128
    }
129
130
    /**
131
     * Output val field for an editable field
132
     *
133
     * @param	string	$text			Text of label (not used in this function)
134
     * @param	string	$htmlname		Name of select field
135
     * @param	string	$value			Value to show/edit
136
     * @param	object	$object			Object
137
     * @param	boolean	$perm			Permission to allow button to edit parameter
138
     * @param	string	$typeofdata		Type of data ('string' by default, 'email', 'amount:99', 'numeric:99', 'text' or 'textarea:rows:cols', 'datepicker' ('day' do not work, don't know why), 'dayhour' or 'datepickerhour', 'ckeditor:dolibarr_zzz:width:height:savemethod:toolbarstartexpanded:rows:cols', 'select:xxx'...)
139
     * @param	string	$editvalue		When in edit mode, use this value as $value instead of value (for example, you can provide here a formated price instead of value). Use '' to use same than $value
140
     * @param	object	$extObject		External object
141
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
142
     * @param	string	$moreparam		More param to add on a href URL
143
     * @param   int     $notabletag     Do no output table tags
144
     * @return  string					HTML edit field
145
     */
146
    function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata='string', $editvalue='', $extObject=null, $custommsg=null, $moreparam='', $notabletag=0)
147
    {
148
        global $conf,$langs,$db;
149
150
        $ret='';
151
152
        // Check parameters
153
        if (empty($typeofdata)) return 'ErrorBadParameter';
154
155
        // When option to edit inline is activated
156
        if (! empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && ! preg_match('/^select;|datehourpicker/',$typeofdata)) // TODO add jquery timepicker
157
        {
158
            $ret.=$this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg);
159
        }
160
        else
161
        {
162
            if (GETPOST('action') == 'edit'.$htmlname)
163
            {
164
                $ret.="\n";
165
                $ret.='<form method="post" action="'.$_SERVER["PHP_SELF"].($moreparam?'?'.$moreparam:'').'">';
166
                $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">';
167
                $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
168
                $ret.='<input type="hidden" name="id" value="'.$object->id.'">';
169
                if (empty($notabletag)) $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
170
                if (empty($notabletag)) $ret.='<tr><td>';
171
                if (preg_match('/^(string|email)/',$typeofdata))
172
                {
173
                    $tmp=explode(':',$typeofdata);
174
                    $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($editvalue?$editvalue:$value).'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>';
175
                }
176
                else if (preg_match('/^(numeric|amount)/',$typeofdata))
177
                {
178
                    $tmp=explode(':',$typeofdata);
179
                    $valuetoshow=price2num($editvalue?$editvalue:$value);
180
                    $ret.='<input type="text" id="'.$htmlname.'" name="'.$htmlname.'" value="'.($valuetoshow!=''?price($valuetoshow):'').'"'.($tmp[1]?' size="'.$tmp[1].'"':'').'>';
181
                }
182
                else if (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata))
183
                {
184
                    $tmp=explode(':',$typeofdata);
185
                    $cols=$tmp[2];
186
                    $morealt='';
187
                    if (preg_match('/%/',$cols))
188
                    {
189
                        $morealt=' style="width: '.$cols.'"';
190
                        $cols='';
191
                    }
192
                    $ret.='<textarea id="'.$htmlname.'" name="'.$htmlname.'" wrap="soft" rows="'.($tmp[1]?$tmp[1]:'20').'"'.($cols?' cols="'.$cols.'"':'').$morealt.'">'.($editvalue?$editvalue:$value).'</textarea>';
193
                }
194
                else if ($typeofdata == 'day' || $typeofdata == 'datepicker')
195
                {
196
                    $ret.=$this->select_date($value,$htmlname,0,0,1,'form'.$htmlname,1,0,1);
197
                }
198
                else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker')
199
                {
200
                    $ret.=$this->select_date($value,$htmlname,1,1,1,'form'.$htmlname,1,0,1);
201
                }
202
                else if (preg_match('/^select;/',$typeofdata))
203
                {
204
                     $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata));
205
                     foreach($arraydata as $val)
206
                     {
207
                         $tmp=explode(':',$val);
208
                         $arraylist[$tmp[0]]=$tmp[1];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arraylist was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arraylist = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
209
                     }
210
                     $ret.=$this->selectarray($htmlname,$arraylist,$value);
0 ignored issues
show
Bug introduced by
The variable $arraylist 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...
211
                }
212
                else if (preg_match('/^ckeditor/',$typeofdata))
213
                {
214
                    $tmp=explode(':',$typeofdata);
215
                    require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
216
                    $doleditor=new DolEditor($htmlname, ($editvalue?$editvalue:$value), ($tmp[2]?$tmp[2]:''), ($tmp[3]?$tmp[3]:'100'), ($tmp[1]?$tmp[1]:'dolibarr_notes'), 'In', ($tmp[5]?$tmp[5]:0), true, true, ($tmp[6]?$tmp[6]:'20'), ($tmp[7]?$tmp[7]:'100'));
217
                    $ret.=$doleditor->Create(1);
218
                }
219
                if (empty($notabletag)) $ret.='</td>';
220
221
                if (empty($notabletag)) $ret.='<td align="left">';
222
                else $ret.='<div class="clearboth"></div>';
223
               	$ret.='<input type="submit" class="button'.(empty($notabletag)?'':' marginrightonly').'" name="modify" value="'.$langs->trans("Modify").'">';
224
               	if (preg_match('/ckeditor|textarea/',$typeofdata) && empty($notabletag)) $ret.='<br>'."\n";
225
               	$ret.='<input type="submit" class="button'.(empty($notabletag)?'':' marginrightonly').'" name="cancel" value="'.$langs->trans("Cancel").'">';
226
               	if (empty($notabletag)) $ret.='</td>';
227
228
               	if (empty($notabletag)) $ret.='</tr></table>'."\n";
229
                $ret.='</form>'."\n";
230
            }
231
            else
232
			{
233
				if (preg_match('/^(email)/',$typeofdata))              $ret.=dol_print_email($value,0,0,0,0,1);
234
                elseif (preg_match('/^(amount|numeric)/',$typeofdata)) $ret.=($value != '' ? price($value,'',$langs,0,-1,-1,$conf->currency) : '');
235
                elseif (preg_match('/^text/',$typeofdata) || preg_match('/^note/',$typeofdata))  $ret.=dol_htmlentitiesbr($value);
236
                elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') $ret.=dol_print_date($value,'day');
237
                elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') $ret.=dol_print_date($value,'dayhour');
238
                else if (preg_match('/^select;/',$typeofdata))
239
                {
240
                    $arraydata=explode(',',preg_replace('/^select;/','',$typeofdata));
241
                    foreach($arraydata as $val)
242
                    {
243
                        $tmp=explode(':',$val);
244
                        $arraylist[$tmp[0]]=$tmp[1];
245
                    }
246
                    $ret.=$arraylist[$value];
247
                }
248
                else if (preg_match('/^ckeditor/',$typeofdata))
249
                {
250
                    $tmpcontent=dol_htmlentitiesbr($value);
251
                    if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB))
252
                    {
253
                        $firstline=preg_replace('/<br>.*/','',$tmpcontent);
254
                        $firstline=preg_replace('/[\n\r].*/','',$firstline);
255
                        $tmpcontent=$firstline.((strlen($firstline) != strlen($tmpcontent))?'...':'');
256
                    }
257
                    $ret.=$tmpcontent;
258
                }
259
                else $ret.=$value;
260
            }
261
        }
262
        return $ret;
263
    }
264
265
    /**
266
     * Output edit in place form
267
     *
268
     * @param	object	$object			Object
269
     * @param	string	$value			Value to show/edit
270
     * @param	string	$htmlname		DIV ID (field name)
271
     * @param	int		$condition		Condition to edit
272
     * @param	string	$inputType		Type of input ('string', 'numeric', 'datepicker' ('day' do not work, don't know why), 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:xxx')
273
     * @param	string	$editvalue		When in edit mode, use this value as $value instead of value
274
     * @param	object	$extObject		External object
275
     * @param	mixed	$custommsg		String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage')
276
     * @return	string   		      	HTML edit in place
277
     */
278
    private function editInPlace($object, $value, $htmlname, $condition, $inputType='textarea', $editvalue=null, $extObject=null, $custommsg=null)
279
    {
280
        global $conf;
281
282
        $out='';
283
284
        // Check parameters
285
        if ($inputType == 'textarea') $value = dol_nl2br($value);
286
        else if (preg_match('/^numeric/',$inputType)) $value = price($value);
287
        else if ($inputType == 'day' || $inputType == 'datepicker') $value = dol_print_date($value, 'day');
288
289
        if ($condition)
290
        {
291
            $element		= false;
292
            $table_element	= false;
293
            $fk_element		= false;
294
            $loadmethod		= false;
295
            $savemethod		= false;
296
            $ext_element	= false;
297
            $button_only	= false;
298
            $inputOption    = '';
299
300
            if (is_object($object))
301
            {
302
                $element = $object->element;
303
                $table_element = $object->table_element;
304
                $fk_element = $object->id;
305
            }
306
307
            if (is_object($extObject))
308
            {
309
                $ext_element = $extObject->element;
310
            }
311
312
            if (preg_match('/^(string|email|numeric)/',$inputType))
313
            {
314
                $tmp=explode(':',$inputType);
315
                $inputType=$tmp[0];
316
                if (! empty($tmp[1])) $inputOption=$tmp[1];
317
                if (! empty($tmp[2])) $savemethod=$tmp[2];
318
				$out.= '<input id="width_'.$htmlname.'" value="'.$inputOption.'" type="hidden"/>'."\n";
319
            }
320
            else if ((preg_match('/^day$/',$inputType)) || (preg_match('/^datepicker/',$inputType)) || (preg_match('/^datehourpicker/',$inputType)))
321
            {
322
                $tmp=explode(':',$inputType);
323
                $inputType=$tmp[0];
324
                if (! empty($tmp[1])) $inputOption=$tmp[1];
325
                if (! empty($tmp[2])) $savemethod=$tmp[2];
326
327
                $out.= '<input id="timestamp" type="hidden"/>'."\n"; // Use for timestamp format
328
            }
329
            else if (preg_match('/^(select|autocomplete)/',$inputType))
330
            {
331
                $tmp=explode(':',$inputType);
332
                $inputType=$tmp[0]; $loadmethod=$tmp[1];
333
                if (! empty($tmp[2])) $savemethod=$tmp[2];
334
                if (! empty($tmp[3])) $button_only=true;
335
            }
336
            else if (preg_match('/^textarea/',$inputType))
337
            {
338
            	$tmp=explode(':',$inputType);
339
            	$inputType=$tmp[0];
340
            	$rows=(empty($tmp[1])?'8':$tmp[1]);
341
            	$cols=(empty($tmp[2])?'80':$tmp[2]);
342
            }
343
            else if (preg_match('/^ckeditor/',$inputType))
344
            {
345
                $tmp=explode(':',$inputType);
346
                $inputType=$tmp[0]; $toolbar=$tmp[1];
347
                if (! empty($tmp[2])) $width=$tmp[2];
348
                if (! empty($tmp[3])) $heigth=$tmp[3];
349
                if (! empty($tmp[4])) $savemethod=$tmp[4];
350
351
                if (! empty($conf->fckeditor->enabled))
352
                {
353
                    $out.= '<input id="ckeditor_toolbar" value="'.$toolbar.'" type="hidden"/>'."\n";
354
                }
355
                else
356
                {
357
                    $inputType = 'textarea';
358
                }
359
            }
360
361
            $out.= '<input id="element_'.$htmlname.'" value="'.$element.'" type="hidden"/>'."\n";
362
            $out.= '<input id="table_element_'.$htmlname.'" value="'.$table_element.'" type="hidden"/>'."\n";
363
            $out.= '<input id="fk_element_'.$htmlname.'" value="'.$fk_element.'" type="hidden"/>'."\n";
364
            $out.= '<input id="loadmethod_'.$htmlname.'" value="'.$loadmethod.'" type="hidden"/>'."\n";
365
            if (! empty($savemethod))	$out.= '<input id="savemethod_'.$htmlname.'" value="'.$savemethod.'" type="hidden"/>'."\n";
366
            if (! empty($ext_element))	$out.= '<input id="ext_element_'.$htmlname.'" value="'.$ext_element.'" type="hidden"/>'."\n";
367
            if (! empty($custommsg))
368
            {
369
            	if (is_array($custommsg))
370
            	{
371
            		if (!empty($custommsg['success']))
372
            			$out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg['success'].'" type="hidden"/>'."\n";
373
            		if (!empty($custommsg['error']))
374
            			$out.= '<input id="errormsg_'.$htmlname.'" value="'.$custommsg['error'].'" type="hidden"/>'."\n";
375
            	}
376
            	else
377
            		$out.= '<input id="successmsg_'.$htmlname.'" value="'.$custommsg.'" type="hidden"/>'."\n";
378
            }
379
            if ($inputType == 'textarea') {
380
            	$out.= '<input id="textarea_'.$htmlname.'_rows" value="'.$rows.'" type="hidden"/>'."\n";
0 ignored issues
show
Bug introduced by
The variable $rows 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...
381
            	$out.= '<input id="textarea_'.$htmlname.'_cols" value="'.$cols.'" type="hidden"/>'."\n";
0 ignored issues
show
Bug introduced by
The variable $cols 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...
382
            }
383
            $out.= '<span id="viewval_'.$htmlname.'" class="viewval_'.$inputType.($button_only ? ' inactive' : ' active').'">'.$value.'</span>'."\n";
384
            $out.= '<span id="editval_'.$htmlname.'" class="editval_'.$inputType.($button_only ? ' inactive' : ' active').' hideobject">'.(! empty($editvalue) ? $editvalue : $value).'</span>'."\n";
385
        }
386
        else
387
        {
388
            $out = $value;
389
        }
390
391
        return $out;
392
    }
393
394
    /**
395
     *	Show a text and picto with tooltip on text or picto.
396
     *  Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip
397
     *
398
     *	@param	string		$text				Text to show
399
     *	@param	string		$htmltext			HTML content of tooltip. Must be HTML/UTF8 encoded.
400
     *	@param	int			$tooltipon			1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2
401
     *	@param	int			$direction			-1=image is before, 0=no image, 1=image is after
402
     *	@param	string		$img				Html code for image (use img_xxx() function to get it)
403
     *	@param	string		$extracss			Add a CSS style to td tags
404
     *	@param	int			$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
405
     *	@param	string		$incbefore			Include code before the text
406
     *	@param	int			$noencodehtmltext	Do not encode into html entity the htmltext
407
     *  @param  int         $tooltiptrigger     ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
408
     *	@return	string							Code html du tooltip (texte+picto)
409
     *	@see	Use function textwithpicto if you can.
410
     *  TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip
411
     */
412
    function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger='')
413
    {
414
        global $conf;
415
416
        if ($incbefore) $text = $incbefore.$text;
417
        if (! $htmltext) return $text;
418
419
        $tag='td';
420
        if ($notabs == 2) $tag='div';
421
        if ($notabs == 3) $tag='span';
422
        // Sanitize tooltip
423
        $htmltext=str_replace("\\","\\\\",$htmltext);
424
        $htmltext=str_replace("\r","",$htmltext);
425
        $htmltext=str_replace("\n","",$htmltext);
426
427
        $extrastyle='';
428
        if ($direction < 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-left: 3px !important;'; }
429
        if ($direction > 0) { $extracss=($extracss?$extracss.' ':'').'inline-block'; $extrastyle='padding: 0px; padding-right: 3px !important;'; }
430
431
        $classfortooltip='classfortooltip';
432
        
433
        $s='';$textfordialog='';
434
        
435
        $htmltext=str_replace('"',"&quot;",$htmltext);
436
        if ($tooltiptrigger != '') 
437
        {
438
            $classfortooltip='classfortooltiponclick';
439
            $textfordialog.='<div style="display: none;" id="idfortooltiponclick_'.$tooltiptrigger.'" class="classfortooltiponclicktext">'.$htmltext.'</div>';
440
        }
441
        if ($tooltipon == 2 || $tooltipon == 3) 
442
        {
443
            $paramfortooltipimg=' class="'.$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'"';
444
            if ($tooltiptrigger == '') $paramfortooltipimg.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on img tag to store tooltip
445
            else $paramfortooltipimg.=' dolid="'.$tooltiptrigger.'"';
446
        }
447
        else $paramfortooltipimg =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag
448
        if ($tooltipon == 1 || $tooltipon == 3) 
449
        {
450
            $paramfortooltiptd=' class="'.$classfortooltip.' inline-block'.($extracss?' '.$extracss:'').'" style="padding: 0px;'.($extrastyle?' '.$extrastyle:'').'" ';
451
            if ($tooltiptrigger == '') $paramfortooltiptd.=' title="'.($noencodehtmltext?$htmltext:dol_escape_htmltag($htmltext,1)).'"'; // Attribut to put on td tag to store tooltip
452
            else $paramfortooltiptd.=' dolid="'.$tooltiptrigger.'"';
453
        }
454
        else $paramfortooltiptd =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag
455
        if (empty($notabs)) $s.='<table class="nobordernopadding" summary=""><tr style="height: auto;">';
456
        elseif ($notabs == 2) $s.='<div class="inline-block">';
457
        // Define value if value is before
458
        if ($direction < 0) {
459
            $s.='<'.$tag.$paramfortooltipimg;
460
            if ($tag == 'td') {
461
                $s .= ' valign="top" width="14"';
462
            }
463
            $s.= '>'.$textfordialog.$img.'</'.$tag.'>';
464
        }
465
        // Use another method to help avoid having a space in value in order to use this value with jquery
466
        // Define label
467
        if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.'</'.$tag.'>';
468
        // Define value if value is after
469
        if ($direction > 0) {
470
            $s.='<'.$tag.$paramfortooltipimg;
471
            if ($tag == 'td') $s .= ' valign="middle" width="14"';
472
            $s.= '>'.$textfordialog.$img.'</'.$tag.'>';
473
        }
474
        if (empty($notabs)) $s.='</tr></table>';
475
		elseif ($notabs == 2) $s.='</div>';
476
477
        return $s;
478
    }
479
480
    /**
481
     *	Show a text with a picto and a tooltip on picto
482
     *
483
     *	@param	string	$text				Text to show
484
     *	@param  string	$htmltext	     	Content of tooltip
485
     *	@param	int		$direction			1=Icon is after text, -1=Icon is before text, 0=no icon
486
     * 	@param	string	$type				Type of picto ('info', 'help', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath
487
     *  @param  string	$extracss           Add a CSS style to td, div or span tag
488
     *  @param  int		$noencodehtmltext   Do not encode into html entity the htmltext
489
     *  @param	int		$notabs				0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span
490
     *  @param  int     $tooltiptrigger     ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key)
491
     * 	@return	string						HTML code of text, picto, tooltip
492
     */
493
    function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger='')
494
    {
495
        global $conf;
496
497
        $alt = '';
498
499
        //For backwards compatibility
500
        if ($type == '0') $type = 'info';
501
        elseif ($type == '1') $type = 'help';
502
503
        // If info or help with no javascript, show only text
504
        if (empty($conf->use_javascript_ajax))
505
        {
506
            if ($type == 'info' || $type == 'help')	return $text;
507
            else
508
            {
509
                $alt = $htmltext;
510
                $htmltext = '';
511
            }
512
        }
513
514
        // If info or help with smartphone, show only text (tooltip can't works)
515
        if (! empty($conf->dol_no_mouse_hover))
516
        {
517
            if ($type == 'info' || $type == 'help') return $text;
518
        }
519
520
        if ($type == 'info') $img = img_help(0, $alt);
521
        elseif ($type == 'help') $img = img_help(($tooltiptrigger != '' ? 2 : 1), $alt);
522
        elseif ($type == 'superadmin') $img = img_picto($alt, 'redstar');
523
        elseif ($type == 'admin') $img = img_picto($alt, 'star');
524
        elseif ($type == 'warning') $img = img_warning($alt);
525
		else $img = img_picto($alt, $type);
526
527
        return $this->textwithtooltip($text, $htmltext, 2, $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger);
528
    }
529
530
    /**
531
     * Generate select HTML to choose massaction
532
     *
533
     * @param	string	$selected		Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default.
534
     * @param	int		$arrayofaction	array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action.
535
     * @param   int     $alwaysvisible  1=select button always visible
536
     * @return	string					Select list
537
     */
538
    function selectMassAction($selected, $arrayofaction, $alwaysvisible=0)
539
    {
540
    	global $conf,$langs,$hookmanager;
541
542
    	if (count($arrayofaction) == 0) return;
543
544
    	$disabled=0;
545
    	$ret='<div class="centpercent center">';
546
    	$ret.='<select data-role="none" class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>';
547
    	$ret.='<option value="0"'.($disabled?' disabled="disabled"':'').'>-- '.$langs->trans("SelectAction").' --</option>';
548
    	foreach($arrayofaction as $code => $label)
0 ignored issues
show
Bug introduced by
The expression $arrayofaction of type integer is not traversable.
Loading history...
549
    	{
550
    		$ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>';
551
    	}
552
    	$ret.='</select>';
553
    	// Warning: if you set submit button to disabled, post using 'Enter' will no more work.
554
    	$ret.='<input type="submit" data-role="none" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">';
555
    	$ret.='</div>';
556
557
    	if (! empty($conf->use_javascript_ajax))
558
    	{
559
        	$ret.='<!-- JS CODE TO ENABLE mass action select -->
560
    		<script type="text/javascript">
561
        		function initCheckForSelect()
562
        		{
563
        			atleastoneselected=0;
564
    	    		jQuery(".checkforselect").each(function( index ) {
565
    	  				/* console.log( index + ": " + $( this ).text() ); */
566
    	  				if ($(this).is(\':checked\')) atleastoneselected++;
567
    	  			});
568
    	  			if (atleastoneselected || '.$alwaysvisible.')
569
    	  			{
570
    	  				jQuery(".massaction").show();
571
        			    '.($selected ? 'if (atleastoneselected) jQuery(".massactionselect").val("'.$selected.'");' : '').'
572
        			    '.($selected ? 'if (! atleastoneselected) jQuery(".massactionselect").val("0");' : '').'
573
    	  			}
574
    	  			else
575
    	  			{
576
    	  				jQuery(".massaction").hide();
577
    	            }
578
        		}
579
    
580
        	jQuery(document).ready(function () {
581
        		initCheckForSelect();
582
        		jQuery(".checkforselect").click(function() {
583
        			initCheckForSelect();
584
    	  		});
585
    	  		jQuery(".massactionselect").change(function() {
586
        			var massaction = $( this ).val();  
587
        			var urlform = $( this ).closest("form").attr("action").replace("#show_files","");
588
        			if (massaction == "builddoc") 
589
                    {
590
                        urlform = urlform + "#show_files";
591
    	            }
592
        			$( this ).closest("form").attr("action", urlform);
593
                    console.log("we select a mass action "+massaction+" - "+urlform);
594
        	        /* Warning: if you set submit button to disabled, post using Enter will no more work
595
        			if ($(this).val() != \'0\')
596
    	  			{
597
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', false);
598
    	  			}
599
    	  			else
600
    	  			{
601
    	  				jQuery(".massactionconfirmed").prop(\'disabled\', true);
602
    	  			}
603
        	        */
604
    	        });
605
        	});
606
    		</script>
607
        	';
608
    	}
609
610
    	return $ret;
611
    }
612
613
    /**
614
     *  Return combo list of activated countries, into language of user
615
     *
616
     *  @param	string	$selected       Id or Code or Label of preselected country
617
     *  @param  string	$htmlname       Name of html select object
618
     *  @param  string	$htmloption     Options html on select object
619
     *  @param	integer	$maxlength		Max length for labels (0=no limit)
620
     *  @param	string	$morecss		More css class
621
     *  @return string           		HTML string with select
622
     */
623
    function select_country($selected='',$htmlname='country_id',$htmloption='',$maxlength=0,$morecss='minwidth300')
624
    {
625
        global $conf,$langs;
626
627
        $langs->load("dict");
628
629
        $out='';
630
        $countryArray=array();
631
		$favorite=array();
632
        $label=array();
633
		$atleastonefavorite=0;
634
635
        $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite";
636
        $sql.= " FROM ".MAIN_DB_PREFIX."c_country";
637
        $sql.= " WHERE active > 0";
638
        //$sql.= " ORDER BY code ASC";
639
640
        dol_syslog(get_class($this)."::select_country", LOG_DEBUG);
641
        $resql=$this->db->query($sql);
642
        if ($resql)
643
        {
644
            $out.= '<select id="select'.$htmlname.'" class="flat maxwidth200onsmartphone selectcountry'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" '.$htmloption.'>';
645
            $num = $this->db->num_rows($resql);
646
            $i = 0;
647
            if ($num)
648
            {
649
                $foundselected=false;
650
651
                while ($i < $num)
652
                {
653
                    $obj = $this->db->fetch_object($resql);
654
                    $countryArray[$i]['rowid'] 		= $obj->rowid;
655
                    $countryArray[$i]['code_iso'] 	= $obj->code_iso;
656
                    $countryArray[$i]['code_iso3'] 	= $obj->code_iso3;
657
                    $countryArray[$i]['label']		= ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso)!="Country".$obj->code_iso?$langs->transnoentitiesnoconv("Country".$obj->code_iso):($obj->label!='-'?$obj->label:''));
658
                    $countryArray[$i]['favorite']   = $obj->favorite;
659
                    $favorite[$i]					= $obj->favorite;
660
					$label[$i] = dol_string_unaccent($countryArray[$i]['label']);
661
                    $i++;
662
                }
663
664
                array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray);
665
666
                foreach ($countryArray as $row)
667
                {
668
                	if ($row['favorite'] && $row['code_iso']) $atleastonefavorite++;
669
					if (empty($row['favorite']) && $atleastonefavorite)
670
					{
671
						$atleastonefavorite=0;
672
						$out.= '<option value="" disabled class="selectoptiondisabledwhite">----------------------</option>';
673
					}
674
                    if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) )
675
                    {
676
                        $foundselected=true;
677
                        $out.= '<option value="'.$row['rowid'].'" selected>';
678
                    }
679
                    else
680
					{
681
                        $out.= '<option value="'.$row['rowid'].'">';
682
                    }
683
                    $out.= dol_trunc($row['label'],$maxlength,'middle');
684
                    if ($row['code_iso']) $out.= ' ('.$row['code_iso'] . ')';
685
                    $out.= '</option>';
686
                }
687
            }
688
            $out.= '</select>';
689
        }
690
        else
691
		{
692
            dol_print_error($this->db);
693
        }
694
695
        // Make select dynamic
696
        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
697
        $out .= ajax_combobox('select'.$htmlname);
698
699
        return $out;
700
    }
701
702
	/**
703
     *  Return select list of incoterms
704
     *
705
     *  @param	string	$selected       		Id or Code of preselected incoterm
706
     *  @param	string	$location_incoterms     Value of input location
707
     *  @param	string	$page       			Defined the form action
708
     *  @param  string	$htmlname       		Name of html select object
709
     *  @param  string	$htmloption     		Options html on select object
710
     * 	@param	int		$forcecombo				Force to use standard combo box (no ajax use)
711
     *  @param	array	$events					Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
712
     *  @return string           				HTML string with select and input
713
     */
714
    function select_incoterms($selected='', $location_incoterms='', $page='', $htmlname='incoterm_id', $htmloption='', $forcecombo=1, $events=array())
715
    {
716
        global $conf,$langs;
717
718
        $langs->load("dict");
719
720
        $out='';
721
        $incotermArray=array();
722
723
        $sql = "SELECT rowid, code";
724
        $sql.= " FROM ".MAIN_DB_PREFIX."c_incoterms";
725
        $sql.= " WHERE active > 0";
726
        $sql.= " ORDER BY code ASC";
727
728
        dol_syslog(get_class($this)."::select_incoterm", LOG_DEBUG);
729
        $resql=$this->db->query($sql);
730
        if ($resql)
731
        {
732
        	if ($conf->use_javascript_ajax && ! $forcecombo)
733
			{
734
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
735
				$out .= ajax_combobox($htmlname, $events);
736
			}
737
738
			if (!empty($page))
739
			{
740
				$out .= '<form method="post" action="'.$page.'">';
741
	            $out .= '<input type="hidden" name="action" value="set_incoterms">';
742
	            $out .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
743
			}
744
745
            $out.= '<select id="'.$htmlname.'" class="flat selectincoterm noenlargeonsmartphone" name="'.$htmlname.'" '.$htmloption.'>';
746
			$out.= '<option value="0">&nbsp;</option>';
747
            $num = $this->db->num_rows($resql);
748
            $i = 0;
749
            if ($num)
750
            {
751
                $foundselected=false;
752
753
                while ($i < $num)
754
                {
755
                    $obj = $this->db->fetch_object($resql);
756
                    $incotermArray[$i]['rowid'] = $obj->rowid;
757
                    $incotermArray[$i]['code'] = $obj->code;
758
                    $i++;
759
                }
760
761
                foreach ($incotermArray as $row)
762
                {
763
                    if ($selected && ($selected == $row['rowid'] || $selected == $row['code']))
764
                    {
765
                        $out.= '<option value="'.$row['rowid'].'" selected>';
766
                    }
767
                    else
768
					{
769
                        $out.= '<option value="'.$row['rowid'].'">';
770
                    }
771
772
                    if ($row['code']) $out.= $row['code'];
773
774
					$out.= '</option>';
775
                }
776
            }
777
            $out.= '</select>';
778
779
			$out .= '<input id="location_incoterms" class="maxwidth100onsmartphone" name="location_incoterms" value="'.$location_incoterms.'">';
780
781
			if (!empty($page))
782
			{
783
	            $out .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'"></form>';
784
			}
785
        }
786
        else
787
		{
788
            dol_print_error($this->db);
789
        }
790
791
        return $out;
792
    }
793
794
    /**
795
     *	Return list of types of lines (product or service)
796
     * 	Example: 0=product, 1=service, 9=other (for external module)
797
     *
798
     *	@param  string	$selected       Preselected type
799
     *	@param  string	$htmlname       Name of field in html form
800
     * 	@param	int		$showempty		Add an empty field
801
     * 	@param	int		$hidetext		Do not show label 'Type' before combo box (used only if there is at least 2 choices to select)
802
     * 	@param	integer	$forceall		1=Force to show products and services in combo list, whatever are activated modules, 0=No force, -1=Force none (and set hidden field to 'service')
803
     *  @return	void
804
     */
805
    function select_type_of_lines($selected='',$htmlname='type',$showempty=0,$hidetext=0,$forceall=0)
806
    {
807
        global $db,$langs,$user,$conf;
808
809
        // If product & services are enabled or both disabled.
810
        if ($forceall > 0 || (empty($forceall) && ! empty($conf->product->enabled) && ! empty($conf->service->enabled))
811
        || (empty($forceall) && empty($conf->product->enabled) && empty($conf->service->enabled)) )
812
        {
813
            if (empty($hidetext)) print $langs->trans("Type").': ';
814
            print '<select class="flat" id="select_'.$htmlname.'" name="'.$htmlname.'">';
815
            if ($showempty)
816
            {
817
                print '<option value="-1"';
818
                if ($selected == -1) print ' selected';
819
                print '>&nbsp;</option>';
820
            }
821
822
            print '<option value="0"';
823
            if (0 == $selected) print ' selected';
824
            print '>'.$langs->trans("Product");
825
826
            print '<option value="1"';
827
            if (1 == $selected) print ' selected';
828
            print '>'.$langs->trans("Service");
829
830
            print '</select>';
831
            //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
832
        }
833
        if (empty($forceall) && empty($conf->product->enabled) && ! empty($conf->service->enabled))
834
        {
835
        	print $langs->trans("Service");
836
            print '<input type="hidden" name="'.$htmlname.'" value="1">';
837
        }
838
        if (empty($forceall) && ! empty($conf->product->enabled) && empty($conf->service->enabled))
839
        {
840
        	print $langs->trans("Product");
841
            print '<input type="hidden" name="'.$htmlname.'" value="0">';
842
        }
843
		if ($forceall < 0)	// This should happened only for contracts when both predefined product and service are disabled.
844
		{
845
            print '<input type="hidden" name="'.$htmlname.'" value="1">';	// By default we set on service for contract. If CONTRACT_SUPPORT_PRODUCTS is set, forceall should be 1 not -1
846
		}
847
    }
848
849
    /**
850
     *	Load into cache cache_types_fees, array of types of fees
851
     *
852
     *	@return     int             Nb of lines loaded, <0 if KO
853
     */
854
    function load_cache_types_fees()
855
    {
856
        global $langs;
857
858
        $num = count($this->cache_types_fees);
859
        if ($num > 0) return 0;    // Cache already loaded
860
861
        dol_syslog(__METHOD__, LOG_DEBUG);
862
863
        $langs->load("trips");
864
865
        $sql = "SELECT c.code, c.label";
866
        $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c";
867
        $sql.= " WHERE active > 0";
868
869
        $resql=$this->db->query($sql);
870
        if ($resql)
871
        {
872
            $num = $this->db->num_rows($resql);
873
            $i = 0;
874
875
            while ($i < $num)
876
            {
877
                $obj = $this->db->fetch_object($resql);
878
879
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
880
                $label=($obj->code != $langs->trans($obj->code) ? $langs->trans($obj->code) : $langs->trans($obj->label));
881
                $this->cache_types_fees[$obj->code] = $label;
882
                $i++;
883
            }
884
885
			asort($this->cache_types_fees);
886
887
            return $num;
888
        }
889
        else
890
		{
891
            dol_print_error($this->db);
892
            return -1;
893
        }
894
    }
895
896
    /**
897
     *	Return list of types of notes
898
     *
899
     *	@param	string		$selected		Preselected type
900
     *	@param  string		$htmlname		Name of field in form
901
     * 	@param	int			$showempty		Add an empty field
902
     * 	@return	void
903
     */
904
    function select_type_fees($selected='',$htmlname='type',$showempty=0)
905
    {
906
        global $user, $langs;
907
908
        dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
909
910
        $this->load_cache_types_fees();
911
912
        print '<select class="flat" name="'.$htmlname.'">';
913
        if ($showempty)
914
        {
915
            print '<option value="-1"';
916
            if ($selected == -1) print ' selected';
917
            print '>&nbsp;</option>';
918
        }
919
920
        foreach($this->cache_types_fees as $key => $value)
921
        {
922
            print '<option value="'.$key.'"';
923
            if ($key == $selected) print ' selected';
924
            print '>';
925
            print $value;
926
            print '</option>';
927
        }
928
929
        print '</select>';
930
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
931
    }
932
933
934
    /**
935
     *  Return HTML code to select a company.
936
     *
937
     *  @param		int			$selected				Preselected products
938
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
939
     *  @param		int			$filter					Filter on thirdparty
940
     *  @param		int			$limit					Limit on number of returned lines
941
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
942
     * 	@param		int			$forcecombo				Force to use combo box
943
     *  @return		string								Return select box for thirdparty.
944
	 *  @deprecated	3.8 Use select_company instead. For exemple $form->select_thirdparty(GETPOST('socid'),'socid','',0) => $form->select_company(GETPOST('socid'),'socid','',1,0,0,array(),0)
945
     */
946
    function select_thirdparty($selected='', $htmlname='socid', $filter='', $limit=20, $ajaxoptions=array(), $forcecombo=0)
947
    {
948
   		return $this->select_thirdparty_list($selected,$htmlname,$filter,1,0,$forcecombo,array(),'',0,$limit);
949
    }
950
951
    /**
952
     *  Output html form to select a third party
953
     *
954
     *	@param	string	$selected       Preselected type
955
     *	@param  string	$htmlname       Name of field in form
956
     *  @param  string	$filter         optional filters criteras (example: 's.rowid <> x', 's.client IN (1,3)')
957
     *	@param	string	$showempty		Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
958
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
959
     * 	@param	int		$forcecombo		Force to use combo box
960
     *  @param	array	$events			Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
961
     *	@param	int		$limit			Maximum number of elements
962
     *  @param	string	$morecss		Add more css styles to the SELECT component
963
     *	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
964
     * 	@return	string					HTML string with select box for thirdparty.
965
     */
966
    function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='')
967
    {
968
    	$out='';
969
970
    	/* TODO Use ajax_autocompleter like for products (not finished)
971
    	if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo)
972
    	{
973
    		$placeholder='';
974
975
    		if ($selected && empty($selected_input_value))
976
    		{
977
    			require_once DOL_DOCUMENT_ROOT.'/societe/ajaxcompanies.php';
978
    			$societe = new Societe($this->db);
979
    			$societe->fetch($selected);
980
    			$selected_input_value=$societe->ref;
981
    		}
982
    		// mode=1 means customers products
983
    		$urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished;
984
    		print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/societe/ajax/company.php', $urloption, $conf->global->COMPANY_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
985
    		if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : ';
986
    		else if ($hidelabel > 1) {
987
    			if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"';
988
    			else $placeholder=' title="'.$langs->trans("RefOrLabel").'"';
989
    			if ($hidelabel == 2) {
990
    				print img_picto($langs->trans("Search"), 'search');
991
    			}
992
    		}
993
    		print '<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' />';
994
    		if ($hidelabel == 3) {
995
    			print img_picto($langs->trans("Search"), 'search');
996
    		}
997
    	}
998
    	else
999
    	{*/
1000
    		$out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam);
1001
    	//}
1002
1003
    	return $out;
1004
    }
1005
1006
    /**
1007
     *  Output html form to select a third party
1008
     *
1009
     *	@param	string	$selected       Preselected type
1010
     *	@param  string	$htmlname       Name of field in form
1011
     *  @param  string	$filter         optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)')
1012
     *	@param	string	$showempty		Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
1013
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
1014
     * 	@param	int		$forcecombo		Force to use combo box
1015
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1016
     *  @param	string	$filterkey		Filter on key value
1017
     *  @param	int		$outputmode		0=HTML select string, 1=Array
1018
     *  @param	int		$limit			Limit number of answers
1019
     *  @param	string	$morecss		Add more css styles to the SELECT component
1020
     *	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
1021
     * 	@return	string					HTML string with
1022
     */
1023
    function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='')
1024
    {
1025
        global $conf,$user,$langs;
1026
1027
        $out=''; $num=0;
1028
        $outarray=array();
1029
1030
        // On recherche les societes
1031
        $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
1032
        $sql.= " FROM ".MAIN_DB_PREFIX ."societe as s";
1033
        if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1034
        $sql.= " WHERE s.entity IN (".getEntity('societe', 1).")";
1035
        if (! empty($user->societe_id)) $sql.= " AND s.rowid = ".$user->societe_id;
1036
        if ($filter) $sql.= " AND (".$filter.")";
1037
        if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
1038
        if (! empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND s.status <> 0";
1039
        // Add criteria
1040
        if ($filterkey && $filterkey != '')
1041
        {
1042
			$sql.=" AND (";
1043
        	if (! empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE))   // Can use index
1044
        	{
1045
        		$sql.="(s.name LIKE '".$this->db->escape($filterkey)."%')";
1046
        	}
1047
        	else
1048
        	{
1049
        		// For natural search
1050
        		$scrit = explode(' ', $filterkey);
1051
        		foreach ($scrit as $crit) {
1052
        			$sql.=" AND (s.name LIKE '%".$this->db->escape($crit)."%')";
1053
        		}
1054
        	}
1055
        	if (! empty($conf->barcode->enabled))
1056
        	{
1057
        		$sql .= " OR s.barcode LIKE '".$this->db->escape($filterkey)."%'";
1058
        	}
1059
        	$sql.=")";
1060
        }
1061
        $sql.=$this->db->order("nom","ASC");
1062
		if ($limit > 0) $sql.=$this->db->plimit($limit);
1063
1064
        dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG);
1065
        $resql=$this->db->query($sql);
1066
        if ($resql)
1067
        {
1068
           	if ($conf->use_javascript_ajax && ! $forcecombo)
1069
            {
1070
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1071
            	$comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT);
1072
            	$out.= $comboenhancement;
1073
            	$nodatarole=($comboenhancement?' data-role="none"':'');
1074
            }
1075
1076
            // Construct $out and $outarray
1077
            $out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.'"'.$nodatarole.'>'."\n";
0 ignored issues
show
Bug introduced by
The variable $nodatarole 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...
1078
1079
            $textifempty='';
1080
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
1081
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
1082
            if (! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT))
1083
            {
1084
                if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty);
1085
                else $textifempty.=$langs->trans("All");
1086
            }
1087
            if ($showempty) $out.= '<option value="-1">'.$textifempty.'</option>'."\n";
1088
1089
            $num = $this->db->num_rows($resql);
1090
            $i = 0;
1091
            if ($num)
1092
            {
1093
                while ($i < $num)
1094
                {
1095
                    $obj = $this->db->fetch_object($resql);
1096
                    $label='';
1097
                    if ($conf->global->SOCIETE_ADD_REF_IN_LIST) {
1098
                    	if (($obj->client) && (!empty($obj->code_client))) {
1099
                    		$label = $obj->code_client. ' - ';
1100
                    	}
1101
                    	if (($obj->fournisseur) && (!empty($obj->code_fournisseur))) {
1102
                    		$label .= $obj->code_fournisseur. ' - ';
1103
                    	}
1104
                    	$label.=' '.$obj->name;
1105
                    }
1106
                    else
1107
                    {
1108
                    	$label=$obj->name;
1109
                    }
1110
1111
					if(!empty($obj->name_alias)) {
1112
						$label.=' ('.$obj->name_alias.')';
1113
					}
1114
1115
                    if ($showtype)
1116
                    {
1117
                        if ($obj->client || $obj->fournisseur) $label.=' (';
1118
                        if ($obj->client == 1 || $obj->client == 3) $label.=$langs->trans("Customer");
1119
                        if ($obj->client == 2 || $obj->client == 3) $label.=($obj->client==3?', ':'').$langs->trans("Prospect");
1120
                        if ($obj->fournisseur) $label.=($obj->client?', ':'').$langs->trans("Supplier");
1121
                        if ($obj->client || $obj->fournisseur) $label.=')';
1122
                    }
1123
                    if ($selected > 0 && $selected == $obj->rowid)
1124
                    {
1125
                        $out.= '<option value="'.$obj->rowid.'" selected>'.$label.'</option>';
1126
                    }
1127
                    else
1128
					{
1129
                        $out.= '<option value="'.$obj->rowid.'">'.$label.'</option>';
1130
                    }
1131
1132
                    array_push($outarray, array('key'=>$obj->rowid, 'value'=>$obj->rowid, 'label'=>$label));
1133
1134
                    $i++;
1135
                    if (($i % 10) == 0) $out.="\n";
1136
                }
1137
            }
1138
            $out.= '</select>'."\n";
1139
        }
1140
        else
1141
        {
1142
            dol_print_error($this->db);
1143
        }
1144
1145
        $this->result=array('nbofthirdparties'=>$num);
1146
1147
        if ($outputmode) return $outarray;
1148
        return $out;
1149
    }
1150
1151
1152
    /**
1153
     *    	Return HTML combo list of absolute discounts
1154
     *
1155
     *    	@param	string	$selected       Id remise fixe pre-selectionnee
1156
     *    	@param  string	$htmlname       Nom champ formulaire
1157
     *    	@param  string	$filter         Criteres optionnels de filtre
1158
     * 		@param	int		$socid			Id of thirdparty
1159
     * 		@param	int		$maxvalue		Max value for lines that can be selected
1160
     * 		@return	int						Return number of qualifed lines in list
1161
     */
1162
    function select_remises($selected, $htmlname, $filter, $socid, $maxvalue=0)
1163
    {
1164
        global $langs,$conf;
1165
1166
        // On recherche les remises
1167
        $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
1168
        $sql.= " re.description, re.fk_facture_source";
1169
        $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re";
1170
        $sql.= " WHERE re.fk_soc = ".(int) $socid;
1171
        $sql.= " AND re.entity = " . $conf->entity;
1172
        if ($filter) $sql.= " AND ".$filter;
1173
        $sql.= " ORDER BY re.description ASC";
1174
1175
        dol_syslog(get_class($this)."::select_remises", LOG_DEBUG);
1176
        $resql=$this->db->query($sql);
1177
        if ($resql)
1178
        {
1179
            print '<select class="flat maxwidthonsmartphone" name="'.$htmlname.'">';
1180
            $num = $this->db->num_rows($resql);
1181
1182
            $qualifiedlines=$num;
1183
1184
            $i = 0;
1185
            if ($num)
1186
            {
1187
                print '<option value="0">&nbsp;</option>';
1188
                while ($i < $num)
1189
                {
1190
                    $obj = $this->db->fetch_object($resql);
1191
                    $desc=dol_trunc($obj->description,40);
1192
                    if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc);
1193
                    if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc);
1194
                    if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc);
1195
1196
                    $selectstring='';
1197
                    if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected';
1198
1199
                    $disabled='';
1200
                    if ($maxvalue > 0 && $obj->amount_ttc > $maxvalue)
1201
                    {
1202
                        $qualifiedlines--;
1203
                        $disabled=' disabled';
1204
                    }
1205
1206
                    print '<option value="'.$obj->rowid.'"'.$selectstring.$disabled.'>'.$desc.' ('.price($obj->amount_ht).' '.$langs->trans("HT").' - '.price($obj->amount_ttc).' '.$langs->trans("TTC").')</option>';
1207
                    $i++;
1208
                }
1209
            }
1210
            print '</select>';
1211
            return $qualifiedlines;
1212
        }
1213
        else
1214
        {
1215
            dol_print_error($this->db);
1216
            return -1;
1217
        }
1218
    }
1219
1220
    /**
1221
     *	Return list of all contacts (for a third party or all)
1222
     *
1223
     *	@param	int		$socid      	Id ot third party or 0 for all
1224
     *	@param  string	$selected   	Id contact pre-selectionne
1225
     *	@param  string	$htmlname  	    Name of HTML field ('none' for a not editable field)
1226
     *	@param  int		$showempty      0=no empty value, 1=add an empty value
1227
     *	@param  string	$exclude        List of contacts id to exclude
1228
     *	@param	string	$limitto		Disable answers that are not id in this array list
1229
     *	@param	integer	$showfunction   Add function into label
1230
     *	@param	string	$moreclass		Add more class to class style
1231
     *	@param	integer	$showsoc	    Add company into label
1232
     * 	@param	int		$forcecombo		Force to use combo box
1233
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1234
     *  @param	bool	$options_only	Return options only (for ajax treatment)
1235
     *	@return	int						<0 if KO, Nb of contact in list if OK
1236
     */
1237
    function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false)
1238
    {
1239
    	print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events);
1240
    	return $this->num;
1241
    }
1242
1243
    /**
1244
     *	Return list of all contacts (for a third party or all)
1245
     *
1246
     *	@param	int		$socid      	Id ot third party or 0 for all
1247
     *	@param  string	$selected   	Id contact pre-selectionne
1248
     *	@param  string	$htmlname  	    Name of HTML field ('none' for a not editable field)
1249
     *	@param  int		$showempty     	0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit)
1250
     *	@param  string	$exclude        List of contacts id to exclude
1251
     *	@param	string	$limitto		Disable answers that are not id in this array list
1252
     *	@param	integer	$showfunction   Add function into label
1253
     *	@param	string	$moreclass		Add more class to class style
1254
     *	@param	bool	$options_only	Return options only (for ajax treatment)
1255
     *	@param	integer	$showsoc	    Add company into label
1256
     * 	@param	int		$forcecombo		Force to use combo box
1257
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
1258
     *	@return	 int					<0 if KO, Nb of contact in list if OK
1259
     */
1260
    function selectcontacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array())
1261
    {
1262
        global $conf,$langs;
1263
1264
        $langs->load('companies');
1265
1266
        $out='';
1267
1268
        // On recherche les societes
1269
        $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste";
1270
        if ($showsoc > 0) $sql.= " , s.nom as company";
1271
        $sql.= " FROM ".MAIN_DB_PREFIX ."socpeople as sp";
1272
        if ($showsoc > 0) $sql.= " LEFT OUTER JOIN  ".MAIN_DB_PREFIX ."societe as s ON s.rowid=sp.fk_soc";
1273
        $sql.= " WHERE sp.entity IN (".getEntity('societe', 1).")";
1274
        if ($socid > 0) $sql.= " AND sp.fk_soc=".$socid;
1275
        if (! empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND sp.statut <> 0";
1276
        $sql.= " ORDER BY sp.lastname ASC";
1277
1278
        dol_syslog(get_class($this)."::select_contacts", LOG_DEBUG);
1279
        $resql=$this->db->query($sql);
1280
        if ($resql)
1281
        {
1282
            $num=$this->db->num_rows($resql);
1283
1284
            if ($conf->use_javascript_ajax && ! $forcecombo && ! $options_only)
1285
            {
1286
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1287
            	$comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT);
1288
            	$out.= $comboenhancement;
1289
            	$nodatarole=($comboenhancement?' data-role="none"':'');
1290
            }
1291
1292
            if ($htmlname != 'none' || $options_only) $out.= '<select class="flat'.($moreclass?' '.$moreclass:'').'" id="'.$htmlname.'" name="'.$htmlname.'"'.$nodatarole.'>';
0 ignored issues
show
Bug introduced by
The variable $nodatarole 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...
1293
            if ($showempty == 1) $out.= '<option value="0"'.($selected=='0'?' selected':'').'></option>';
1294
            if ($showempty == 2) $out.= '<option value="0"'.($selected=='0'?' selected':'').'>'.$langs->trans("Internal").'</option>';
1295
            $num = $this->db->num_rows($resql);
1296
            $i = 0;
1297
            if ($num)
1298
            {
1299
                include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
1300
                $contactstatic=new Contact($this->db);
1301
1302
                while ($i < $num)
1303
                {
1304
                    $obj = $this->db->fetch_object($resql);
1305
1306
                    $contactstatic->id=$obj->rowid;
1307
                    $contactstatic->lastname=$obj->lastname;
1308
                    $contactstatic->firstname=$obj->firstname;
1309
					if ($obj->statut == 1){
1310
                    if ($htmlname != 'none')
1311
                    {
1312
                        $disabled=0;
1313
                        if (is_array($exclude) && count($exclude) && in_array($obj->rowid,$exclude)) $disabled=1;
1314
                        if (is_array($limitto) && count($limitto) && ! in_array($obj->rowid,$limitto)) $disabled=1;
1315
                        if ($selected && $selected == $obj->rowid)
1316
                        {
1317
                            $out.= '<option value="'.$obj->rowid.'"';
1318
                            if ($disabled) $out.= ' disabled';
1319
                            $out.= ' selected>';
1320
                            $out.= $contactstatic->getFullName($langs);
1321
                            if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')';
1322
                            if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')';
1323
                            $out.= '</option>';
1324
                        }
1325
                        else
1326
                        {
1327
                            $out.= '<option value="'.$obj->rowid.'"';
1328
                            if ($disabled) $out.= ' disabled';
1329
                            $out.= '>';
1330
                            $out.= $contactstatic->getFullName($langs);
1331
                            if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')';
1332
                            if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')';
1333
                            $out.= '</option>';
1334
                        }
1335
                    }
1336
                    else
1337
					{
1338
                        if ($selected == $obj->rowid)
1339
                        {
1340
                            $out.= $contactstatic->getFullName($langs);
1341
                            if ($showfunction && $obj->poste) $out.= ' ('.$obj->poste.')';
1342
                            if (($showsoc > 0) && $obj->company) $out.= ' - ('.$obj->company.')';
1343
                        }
1344
                    }
1345
				}
1346
                    $i++;
1347
                }
1348
            }
1349
            else
1350
			{
1351
            	$out.= '<option value="-1"'.($showempty==2?'':' selected').' disabled>'.$langs->trans($socid?"NoContactDefinedForThirdParty":"NoContactDefined").'</option>';
1352
            }
1353
            if ($htmlname != 'none' || $options_only)
1354
            {
1355
                $out.= '</select>';
1356
            }
1357
1358
            $this->num = $num;
1359
            return $out;
1360
        }
1361
        else
1362
        {
1363
            dol_print_error($this->db);
1364
            return -1;
1365
        }
1366
    }
1367
1368
    /**
1369
     *	Return select list of users
1370
     *
1371
     *  @param	string	$selected       Id user preselected
1372
     *  @param  string	$htmlname       Field name in form
1373
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
1374
     *  @param  array	$exclude        Array list of users id to exclude
1375
     * 	@param	int		$disabled		If select list must be disabled
1376
     *  @param  array	$include        Array list of users id to include
1377
     * 	@param	int		$enableonly		Array list of users id to be enabled. All other must be disabled
1378
     *  @param	int		$force_entity	0 or Id of environment to force
1379
     * 	@return	void
1380
     *  @deprecated
1381
     *  @see select_dolusers()
1382
     */
1383
    function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude='',$disabled=0,$include='',$enableonly='',$force_entity=0)
1384
    {
1385
        print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity);
1386
    }
1387
1388
    /**
1389
     *	Return select list of users
1390
     *
1391
     *  @param	string	$selected       User id or user object of user preselected. If -1, we use id of current user.
1392
     *  @param  string	$htmlname       Field name in form
1393
     *  @param  int		$show_empty     0=list with no empty value, 1=add also an empty value into list
1394
     *  @param  array	$exclude        Array list of users id to exclude
1395
     * 	@param	int		$disabled		If select list must be disabled
1396
     *  @param  array|string	$include        Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me
1397
     * 	@param	array	$enableonly		Array list of users id to be enabled. All other must be disabled
1398
     *  @param	int		$force_entity	0 or Id of environment to force
1399
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1400
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1401
     *  @param	string	$morefilter		Add more filters into sql request
1402
     *  @param	integer	$show_every		0=default list, 1=add also a value "Everybody" at beginning of list
1403
     *  @param	string	$enableonlytext	If option $enableonly is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty.
1404
     *  @param	string	$morecss		More css
1405
     *  @param  int     $noactive       Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on).
1406
     * 	@return	string					HTML select string
1407
     *  @see select_dolgroups
1408
     */
1409
    function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0)
1410
    {
1411
        global $conf,$user,$langs;
1412
1413
        // If no preselected user defined, we take current user
1414
        if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty($conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE)) $selected=$user->id;
1415
1416
        $excludeUsers=null;
1417
        $includeUsers=null;
1418
1419
        // Permettre l'exclusion d'utilisateurs
1420
        if (is_array($exclude))	$excludeUsers = implode(",",$exclude);
1421
        // Permettre l'inclusion d'utilisateurs
1422
        if (is_array($include))	$includeUsers = implode(",",$include);
1423
		else if ($include == 'hierarchy')
1424
		{
1425
			// Build list includeUsers to have only hierarchy
1426
			$includeUsers = implode(",",$user->getAllChildIds(0));
1427
		}
1428
		else if ($include == 'hierarchyme')
1429
		{
1430
		    // Build list includeUsers to have only hierarchy and current user
1431
		    $includeUsers = implode(",",$user->getAllChildIds(1));
1432
		}
1433
1434
        $out='';
1435
1436
        // On recherche les utilisateurs
1437
        $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity";
1438
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
1439
        {
1440
            $sql.= ", e.label";
1441
        }
1442
        $sql.= " FROM ".MAIN_DB_PREFIX ."user as u";
1443
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
1444
        {
1445
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX ."entity as e ON e.rowid=u.entity";
1446
            if ($force_entity) $sql.= " WHERE u.entity IN (0,".$force_entity.")";
1447
            else $sql.= " WHERE u.entity IS NOT NULL";
1448
        }
1449
        else
1450
       {
1451
        	if (! empty($conf->multicompany->transverse_mode))
1452
        	{
1453
        		$sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1454
        		$sql.= " WHERE ug.fk_user = u.rowid";
1455
        		$sql.= " AND ug.entity = ".$conf->entity;
1456
        	}
1457
        	else
1458
        	{
1459
        		$sql.= " WHERE u.entity IN (0,".$conf->entity.")";
1460
        	}
1461
        }
1462
        if (! empty($user->societe_id)) $sql.= " AND u.fk_soc = ".$user->societe_id;
1463
        if (is_array($exclude) && $excludeUsers) $sql.= " AND u.rowid NOT IN (".$excludeUsers.")";
1464
        if ($includeUsers) $sql.= " AND u.rowid IN (".$includeUsers.")";
1465
        if (! empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive) $sql.= " AND u.statut <> 0";
1466
        if (! empty($morefilter)) $sql.=" ".$morefilter;
1467
        $sql.= " ORDER BY u.lastname ASC";
1468
1469
        dol_syslog(get_class($this)."::select_dolusers", LOG_DEBUG);
1470
        $resql=$this->db->query($sql);
1471
        if ($resql)
1472
        {
1473
            $num = $this->db->num_rows($resql);
1474
            $i = 0;
1475
            if ($num)
1476
            {
1477
           		// Enhance with select2
1478
           		$nodatarole='';
1479
		        if ($conf->use_javascript_ajax)
1480
		        {
1481
		            include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1482
		            $comboenhancement = ajax_combobox($htmlname);
1483
		            $out.=$comboenhancement;
1484
		            $nodatarole=($comboenhancement?' data-role="none"':'');
1485
		        }
1486
1487
		        // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined
1488
                $out.= '<select class="flat'.($morecss?' minwidth100 '.$morecss:' minwidth200').'" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').$nodatarole.'>';
1489
                if ($show_empty) $out.= '<option value="-1"'.((empty($selected) || $selected==-1)?' selected':'').'>&nbsp;</option>'."\n";
1490
				if ($show_every) $out.= '<option value="-2"'.(($selected==-2)?' selected':'').'>-- '.$langs->trans("Everybody").' --</option>'."\n";
1491
1492
                $userstatic=new User($this->db);
1493
1494
                while ($i < $num)
1495
                {
1496
                    $obj = $this->db->fetch_object($resql);
1497
1498
                    $userstatic->id=$obj->rowid;
1499
                    $userstatic->lastname=$obj->lastname;
1500
                    $userstatic->firstname=$obj->firstname;
1501
1502
                    $disableline='';
1503
                    if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=($enableonlytext?$enableonlytext:'1');
1504
1505
                    if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid))
1506
                    {
1507
                        $out.= '<option value="'.$obj->rowid.'"';
1508
                        if ($disableline) $out.= ' disabled';
1509
                        $out.= ' selected>';
1510
                    }
1511
                    else
1512
                    {
1513
                        $out.= '<option value="'.$obj->rowid.'"';
1514
                        if ($disableline) $out.= ' disabled';
1515
                        $out.= '>';
1516
                    }
1517
1518
                    $out.= $userstatic->getFullName($langs, 0, -1, $maxlength);
1519
                    // Complete name with more info
1520
                    $moreinfo=0;
1521
                    if (! empty($conf->global->MAIN_SHOW_LOGIN))
1522
                    {
1523
                    	$out.= ($moreinfo?' - ':' (').$obj->login;
1524
                    	$moreinfo++;
1525
                    }
1526
                    if ($showstatus >= 0)
1527
                    {
1528
                    	if ($obj->statut == 1 && $showstatus == 1)
1529
                    	{
1530
                    		$out.=($moreinfo?' - ':' (').$langs->trans('Enabled');
1531
                    		$moreinfo++;
1532
                    	}
1533
						if ($obj->statut == 0)
1534
						{
1535
							$out.=($moreinfo?' - ':' (').$langs->trans('Disabled');
1536
							$moreinfo++;
1537
						}
1538
					}
1539
                    if (! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && ! $user->entity)
1540
                    {
1541
                        if ($obj->admin && ! $obj->entity)
1542
                        {
1543
                        	$out.=($moreinfo?' - ':' (').$langs->trans("AllEntities");
1544
                        	$moreinfo++;
1545
                        }
1546
                        else
1547
                     {
1548
                        	$out.=($moreinfo?' - ':' (').($obj->label?$obj->label:$langs->trans("EntityNameNotDefined"));
1549
                        	$moreinfo++;
1550
                     	}
1551
                    }
1552
					$out.=($moreinfo?')':'');
1553
					if ($disableline && $disableline != '1')
1554
					{
1555
						$out.=' - '.$disableline;	// This is text from $enableonlytext parameter
1556
					}
1557
                    $out.= '</option>';
1558
1559
                    $i++;
1560
                }
1561
            }
1562
            else
1563
            {
1564
                $out.= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'" disabled>';
1565
                $out.= '<option value="">'.$langs->trans("None").'</option>';
1566
            }
1567
            $out.= '</select>';
1568
        }
1569
        else
1570
        {
1571
            dol_print_error($this->db);
1572
        }
1573
1574
        return $out;
1575
    }
1576
1577
1578
    /**
1579
     *	Return select list of users. Selected users are stored into session.
1580
     *  List of users are provided into $_SESSION['assignedtouser'].
1581
     *
1582
     *  @param  string	$action         Value for $action
1583
     *  @param  string	$htmlname       Field name in form
1584
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
1585
     *  @param  array	$exclude        Array list of users id to exclude
1586
     * 	@param	int		$disabled		If select list must be disabled
1587
     *  @param  array	$include        Array list of users id to include or 'hierarchy' to have only supervised users
1588
     * 	@param	array	$enableonly		Array list of users id to be enabled. All other must be disabled
1589
     *  @param	int		$force_entity	0 or Id of environment to force
1590
     *  @param	int		$maxlength		Maximum length of string into list (0=no limit)
1591
     *  @param	int		$showstatus		0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
1592
     *  @param	string	$morefilter		Add more filters into sql request
1593
     * 	@return	string					HTML select string
1594
     *  @see select_dolgroups
1595
     */
1596
    function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='')
1597
    {
1598
        global $conf,$user,$langs;
1599
1600
        $userstatic=new User($this->db);
1601
		$out='';
1602
1603
        // Method with no ajax
1604
        //$out.='<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1605
        if ($action == 'view')
1606
        {
1607
			$out.='';
1608
        }
1609
		else
1610
		{
1611
			$out.='<input type="hidden" class="removedassignedhidden" name="removedassigned" value="">';
1612
			$out.='<script type="text/javascript" language="javascript">jQuery(document).ready(function () {    jQuery(".removedassigned").click(function() {        jQuery(".removedassignedhidden").val(jQuery(this).val());    });})</script>';
1613
			$out.=$this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter);
1614
			$out.=' <input type="submit" class="button valignmiddle" name="'.$action.'assignedtouser" value="'.dol_escape_htmltag($langs->trans("Add")).'">';
1615
		}
1616
		$assignedtouser=array();
1617
		if (!empty($_SESSION['assignedtouser']))
1618
		{
1619
			$assignedtouser=json_decode($_SESSION['assignedtouser'], true);
1620
		}
1621
		$nbassignetouser=count($assignedtouser);
1622
1623
		if ($nbassignetouser && $action != 'view') $out.='<br>';
1624
		if ($nbassignetouser) $out.='<div class="myavailability">';
1625
		$i=0; $ownerid=0;
1626
		foreach($assignedtouser as $key => $value)
1627
		{
1628
			if ($value['id'] == $ownerid) continue;
1629
			$userstatic->fetch($value['id']);
1630
			$out.=$userstatic->getNomUrl(1);
1631
			if ($i == 0) { $ownerid = $value['id']; $out.=' ('.$langs->trans("Owner").')'; }
1632
			if ($nbassignetouser > 1 && $action != 'view') $out.=' <input type="image" style="border: 0px;" src="'.img_picto($langs->trans("Remove"), 'delete', '', 0, 1).'" value="'.$userstatic->id.'" class="removedassigned" id="removedassigned_'.$userstatic->id.'" name="removedassigned_'.$userstatic->id.'">';
1633
			//$out.=' '.($value['mandatory']?$langs->trans("Mandatory"):$langs->trans("Optional"));
1634
			//$out.=' '.($value['transparency']?$langs->trans("Busy"):$langs->trans("NotBusy"));
1635
			$out.='<br>';
1636
			$i++;
1637
		}
1638
		if ($nbassignetouser) $out.='</div>';
1639
1640
		//$out.='</form>';
1641
        return $out;
1642
    }
1643
1644
1645
    /**
1646
     *  Return list of products for customer in Ajax if Ajax activated or go to select_produits_list
1647
     *
1648
     *  @param		int			$selected				Preselected products
1649
     *  @param		string		$htmlname				Name of HTML select field (must be unique in page)
1650
     *  @param		int			$filtertype				Filter on product type (''=nofilter, 0=product, 1=service)
1651
     *  @param		int			$limit					Limit on number of returned lines
1652
     *  @param		int			$price_level			Level of price to show
1653
     *  @param		int			$status					-1=Return all products, 0=Products not on sell, 1=Products on sell
1654
     *  @param		int			$finished				2=all, 1=finished, 0=raw material
1655
     *  @param		string		$selected_input_value	Value of preselected input text (for use with ajax)
1656
     *  @param		int			$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
1657
     *  @param		array		$ajaxoptions			Options for ajax_autocompleter
1658
     *  @param      int			$socid					Thirdparty Id (to get also price dedicated to this customer)
1659
     *  @param		string		$showempty				'' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
1660
     * 	@param		int			$forcecombo				Force to use combo box
1661
     *  @param      string      $morecss                Add more css on select
1662
     *  @param      int         $hidepriceinlabel       1=Hide prices in label
1663
     *  @param      string      $warehouseStatus        warehouse status filter, following comma separated filter options can be used
1664
     *										            'warehouseopen' = select products from open warehouses,
1665
	 *										            'warehouseclosed' = select products from closed warehouses,
1666
	 *										            'warehouseinternal' = select products from warehouses for internal correct/transfer only
1667
     *  @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...])
1668
     *  @return		void
1669
     */
1670
    function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(), $socid=0, $showempty='1', $forcecombo=0, $morecss='', $hidepriceinlabel=0, $warehouseStatus='', $selected_combinations = array())
1671
    {
1672
        global $langs,$conf;
1673
1674
        $price_level = (! empty($price_level) ? $price_level : 0);
1675
1676
        if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
1677
        {
1678
        	$placeholder='';
1679
1680
            if ($selected && empty($selected_input_value))
1681
            {
1682
                require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1683
                $producttmpselect = new Product($this->db);
1684
                $producttmpselect->fetch($selected);
1685
                $selected_input_value=$producttmpselect->ref;
1686
                unset($producttmpselect);
1687
            }
1688
            // mode=1 means customers products
1689
            $urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished.'&warehousestatus='.$warehouseStatus;
1690
            //Price by customer
1691
            if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1692
            	$urloption.='&socid='.$socid;
1693
            }
1694
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
1695
1696
			if (!empty($conf->variants->enabled)) {
1697
				?>
1698
				<script>
1699
1700
					selected = <?php echo json_encode($selected_combinations) ?>;
1701
					combvalues = {};
1702
1703
					jQuery(document).ready(function () {
1704
1705
						jQuery("input[name='prod_entry_mode']").change(function () {
1706
							if (jQuery(this).val() == 'free') {
1707
								jQuery('div#attributes_box').empty();
1708
							}
1709
						});
1710
1711
						jQuery("input#<?php echo $htmlname ?>").change(function () {
1712
1713
							if (!jQuery(this).val()) {
1714
								jQuery('div#attributes_box').empty();
1715
								return;
1716
							}
1717
1718
							jQuery.getJSON("<?php echo dol_buildpath('/variants/ajax/getCombinations.php', 2) ?>", {
1719
								id: jQuery(this).val()
1720
							}, function (data) {
1721
								jQuery('div#attributes_box').empty();
1722
1723
								jQuery.each(data, function (key, val) {
1724
1725
									combvalues[val.id] = val.values;
1726
1727
									var span = jQuery(document.createElement('div')).css({
1728
										'display': 'table-row'
1729
									});
1730
1731
									span.append(
1732
										jQuery(document.createElement('div')).text(val.label).css({
1733
											'font-weight': 'bold',
1734
											'display': 'table-cell',
1735
											'text-align': 'right'
1736
										})
1737
									);
1738
1739
									var html = jQuery(document.createElement('select')).attr('name', 'combinations[' + val.id + ']').css({
1740
										'margin-left': '15px',
1741
										'white-space': 'pre'
1742
									}).append(
1743
										jQuery(document.createElement('option')).val('')
1744
									);
1745
1746
									jQuery.each(combvalues[val.id], function (key, val) {
1747
										var tag = jQuery(document.createElement('option')).val(val.id).html(val.value);
1748
1749
										if (selected[val.fk_product_attribute] == val.id) {
1750
											tag.attr('selected', 'selected');
1751
										}
1752
1753
										html.append(tag);
1754
									});
1755
1756
									span.append(html);
1757
									jQuery('div#attributes_box').append(span);
1758
								});
1759
							})
1760
						});
1761
1762
						<?php if ($selected): ?>
1763
						jQuery("input#<?php echo $htmlname ?>").change();
1764
						<?php endif ?>
1765
					});
1766
				</script>
1767
                <?php
1768
            }
1769
            if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : ';
1770
            else if ($hidelabel > 1) {
1771
            	if (! empty($conf->global->MAIN_HTML5_PLACEHOLDER)) $placeholder=' placeholder="'.$langs->trans("RefOrLabel").'"';
1772
            	else $placeholder=' title="'.$langs->trans("RefOrLabel").'"';
1773
            	if ($hidelabel == 2) {
1774
            		print img_picto($langs->trans("Search"), 'search');
1775
            	}
1776
            }
1777
            print '<input type="text" class="minwidth100" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' '.(!empty($conf->global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />';
1778
            if ($hidelabel == 3) {
1779
            	print img_picto($langs->trans("Search"), 'search');
1780
            }
1781
        }
1782
        else
1783
		{
1784
            print $this->select_produits_list($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished,0,$socid,$showempty,$forcecombo,$morecss,$hidepriceinlabel, $warehouseStatus);
1785
        }
1786
    }
1787
1788
    /**
1789
     *	Return list of products for a customer
1790
     *
1791
     *	@param      int		$selected           Preselected product
1792
     *	@param      string	$htmlname           Name of select html
1793
     *  @param		string	$filtertype         Filter on product type (''=nofilter, 0=product, 1=service)
1794
     *	@param      int		$limit              Limit on number of returned lines
1795
     *	@param      int		$price_level        Level of price to show
1796
     * 	@param      string	$filterkey          Filter on product
1797
     *	@param		int		$status             -1=Return all products, 0=Products not on sell, 1=Products on sell
1798
     *  @param      int		$finished           Filter on finished field: 2=No filter
1799
     *  @param      int		$outputmode         0=HTML select string, 1=Array
1800
     *  @param      int		$socid     		    Thirdparty Id (to get also price dedicated to this customer)
1801
     *  @param		string	$showempty		    '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text.
1802
     * 	@param		int		$forcecombo		    Force to use combo box
1803
     *  @param      string  $morecss            Add more css on select
1804
     *  @param      int     $hidepriceinlabel   1=Hide prices in label
1805
     *  @param      string  $warehouseStatus    warehouse status filter, following comma separated filter options can be used
1806
     *										    'warehouseopen' = select products from open warehouses,
1807
	 *										    'warehouseclosed' = select products from closed warehouses,
1808
	 *										    'warehouseinternal' = select products from warehouses for internal correct/transfer only
1809
     *  @return     array    				    Array of keys for json
1810
     */
1811
    function select_produits_list($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$filterkey='',$status=1,$finished=2,$outputmode=0,$socid=0,$showempty='1',$forcecombo=0,$morecss='',$hidepriceinlabel=0, $warehouseStatus='')
1812
    {
1813
        global $langs,$conf,$user,$db;
1814
1815
        $out='';
1816
        $outarray=array();
1817
1818
        $warehouseStatusArray = array();
1819
        if (! empty($warehouseStatus))
1820
        {
1821
            require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
1822
            if (preg_match('/warehouseclosed/', $warehouseStatus))
1823
            {
1824
                $warehouseStatusArray[] = Entrepot::STATUS_CLOSED;
1825
            }
1826
            if (preg_match('/warehouseopen/', $warehouseStatus))
1827
            {
1828
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_ALL;
1829
            }
1830
            if (preg_match('/warehouseinternal/', $warehouseStatus))
1831
            {
1832
                $warehouseStatusArray[] = Entrepot::STATUS_OPEN_INTERNAL;
1833
            }
1834
        }
1835
1836
        $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression";
1837
        (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock";
1838
1839
        $sql = "SELECT ";
1840
        $sql.= $selectFields . $selectFieldsGrouped;
1841
        //Price by customer
1842
        if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1843
        	$sql.=' ,pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
1844
        	$sql.=' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
1845
            $selectFields.= ", idprodcustprice, custprice, custprice_ttc, custprice_base_type, custtva_tx";
1846
        }
1847
1848
        // Multilang : we add translation
1849
        if (! empty($conf->global->MAIN_MULTILANGS))
1850
        {
1851
            $sql.= ", pl.label as label_translated";
1852
            $selectFields.= ", label_translated";
1853
        }
1854
		// Price by quantity
1855
		if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
1856
		{
1857
			$sql.= ", (SELECT pp.rowid FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
1858
			if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level;
1859
			$sql.= " ORDER BY date_price";
1860
			$sql.= " DESC LIMIT 1) as price_rowid";
1861
			$sql.= ", (SELECT pp.price_by_qty FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
1862
			if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level;
1863
			$sql.= " ORDER BY date_price";
1864
			$sql.= " DESC LIMIT 1) as price_by_qty";
1865
            $selectFields.= ", price_rowid, price_by_qty";
1866
		}
1867
        $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
1868
        if (count($warehouseStatusArray))
1869
        {
1870
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid";
1871
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid";
1872
        }
1873
1874
        //Price by customer
1875
        if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
1876
        	$sql.=" LEFT JOIN  ".MAIN_DB_PREFIX."product_customer_price as pcp ON pcp.fk_soc=".$socid." AND pcp.fk_product=p.rowid";
1877
        }
1878
        // Multilang : we add translation
1879
        if (! empty($conf->global->MAIN_MULTILANGS))
1880
        {
1881
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang='". $langs->getDefaultLang() ."'";
1882
        }
1883
1884
        if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
1885
            $sql .= " LEFT JOIN llx_product_attribute_combination pac ON pac.fk_product_child = p.rowid";
1886
        }
1887
1888
        $sql.= ' WHERE p.entity IN ('.getEntity('product', 1).')';
1889
        if (count($warehouseStatusArray))
1890
        {
1891
            $sql.= ' AND (p.fk_product_type = 1 OR e.statut IN ('.implode(',',$warehouseStatusArray).'))';
1892
        }
1893
1894
        if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
1895
            $sql .= " AND pac.rowid IS NULL";
1896
        }
1897
1898
        if ($finished == 0)
1899
        {
1900
            $sql.= " AND p.finished = ".$finished;
1901
        }
1902
        elseif ($finished == 1)
1903
        {
1904
            $sql.= " AND p.finished = ".$finished;
1905
            if ($status >= 0)  $sql.= " AND p.tosell = ".$status;
1906
        }
1907
        elseif ($status >= 0)
1908
        {
1909
            $sql.= " AND p.tosell = ".$status;
1910
        }
1911
        if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$filtertype;
1912
        // Add criteria on ref/label
1913
        if ($filterkey != '')
1914
        {
1915
        	$sql.=' AND (';
1916
        	$prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':'';	// Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
1917
            // For natural search
1918
            $scrit = explode(' ', $filterkey);
1919
            $i=0;
1920
            if (count($scrit) > 1) $sql.="(";
1921
            foreach ($scrit as $crit)
1922
            {
1923
            	if ($i > 0) $sql.=" AND ";
1924
                $sql.="(p.ref LIKE '".$db->escape($prefix.$crit)."%' OR p.label LIKE '".$db->escape($prefix.$crit)."%'";
1925
                if (! empty($conf->global->MAIN_MULTILANGS)) $sql.=" OR pl.label LIKE '".$db->escape($prefix.$crit)."%'";
1926
                $sql.=")";
1927
                $i++;
1928
            }
1929
            if (count($scrit) > 1) $sql.=")";
1930
          	if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$db->escape($prefix.$filterkey)."%'";
1931
        	$sql.=')';
1932
        }
1933
        if (count($warehouseStatusArray))
1934
        {
1935
            $sql.= ' GROUP BY'.$selectFields;
1936
        }
1937
        $sql.= $db->order("p.ref");
1938
        $sql.= $db->plimit($limit);
1939
1940
        // Build output string
1941
        dol_syslog(get_class($this)."::select_produits_list search product", LOG_DEBUG);
1942
        $result=$this->db->query($sql);
1943
        if ($result)
1944
        {
1945
            require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
1946
            require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
1947
            $num = $this->db->num_rows($result);
1948
1949
            $events=null;
1950
1951
            if ($conf->use_javascript_ajax && ! $forcecombo)
1952
            {
1953
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
1954
            	$comboenhancement =ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT);
1955
            	$out.= $comboenhancement;
1956
            	$nodatarole=($comboenhancement?' data-role="none"':'');
1957
            }
1958
1959
            $out.='<select class="flat'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'"'.$nodatarole.'>';
0 ignored issues
show
Bug introduced by
The variable $nodatarole 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...
1960
1961
            $textifempty='';
1962
            // Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
1963
            //if (! empty($conf->use_javascript_ajax) || $forcecombo) $textifempty='';
1964
            if (! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
1965
            {
1966
                if ($showempty && ! is_numeric($showempty)) $textifempty=$langs->trans($showempty);
1967
                else $textifempty.=$langs->trans("All");
1968
            }
1969
            if ($showempty) $out.='<option value="0" selected>'.$textifempty.'</option>';
1970
1971
            $i = 0;
1972
            while ($num && $i < $num)
1973
            {
1974
            	$opt = '';
1975
				$optJson = array();
1976
				$objp = $this->db->fetch_object($result);
1977
1978
				if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1)
1979
				{ // Price by quantity will return many prices for the same product
1980
					$sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise";
1981
					$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
1982
					$sql.= " WHERE fk_product_price=".$objp->price_rowid;
1983
					$sql.= " ORDER BY quantity ASC";
1984
1985
					dol_syslog(get_class($this)."::select_produits_list search price by qty", LOG_DEBUG);
1986
					$result2 = $this->db->query($sql);
1987
					if ($result2)
1988
					{
1989
						$nb_prices = $this->db->num_rows($result2);
1990
						$j = 0;
1991
						while ($nb_prices && $j < $nb_prices) {
1992
							$objp2 = $this->db->fetch_object($result2);
1993
1994
							$objp->quantity = $objp2->quantity;
1995
							$objp->price = $objp2->price;
1996
							$objp->unitprice = $objp2->unitprice;
1997
							$objp->remise_percent = $objp2->remise_percent;
1998
							$objp->remise = $objp2->remise;
1999
							$objp->price_by_qty_rowid = $objp2->rowid;
2000
2001
							$this->constructProductListOption($objp, $opt, $optJson, 0, $selected, $hidepriceinlabel);
2002
2003
							$j++;
2004
2005
							// Add new entry
2006
							// "key" value of json key array is used by jQuery automatically as selected value
2007
							// "label" value of json key array is used by jQuery automatically as text for combo box
2008
							$out.=$opt;
2009
							array_push($outarray, $optJson);
2010
						}
2011
					}
2012
				}
2013
				else
2014
				{
2015
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_price_expression)) {
2016
                        $price_product = new Product($this->db);
2017
                        $price_product->fetch($objp->rowid, '', '', 1);
2018
                        $priceparser = new PriceParser($this->db);
2019
                        $price_result = $priceparser->parseProduct($price_product);
2020
                        if ($price_result >= 0) {
2021
                            $objp->price = $price_result;
2022
                            $objp->unitprice = $price_result;
2023
                            //Calculate the VAT
2024
                            $objp->price_ttc = price2num($objp->price) * (1 + ($objp->tva_tx / 100));
2025
                            $objp->price_ttc = price2num($objp->price_ttc,'MU');
2026
                        }
2027
                    }
2028
					$this->constructProductListOption($objp, $opt, $optJson, $price_level, $selected, $hidepriceinlabel);
2029
					// Add new entry
2030
					// "key" value of json key array is used by jQuery automatically as selected value
2031
					// "label" value of json key array is used by jQuery automatically as text for combo box
2032
					$out.=$opt;
2033
					array_push($outarray, $optJson);
2034
				}
2035
2036
                $i++;
2037
            }
2038
2039
            $out.='</select>';
2040
2041
            $this->db->free($result);
2042
2043
            if (empty($outputmode)) return $out;
2044
            return $outarray;
2045
        }
2046
        else
2047
		{
2048
            dol_print_error($db);
2049
        }
2050
    }
2051
2052
    /**
2053
     * constructProductListOption
2054
     *
2055
     * @param 	resultset	$objp			    Resultset of fetch
2056
     * @param 	string		$opt			    Option (var used for returned value in string option format)
2057
     * @param 	string		$optJson		    Option (var used for returned value in json format)
2058
     * @param 	int			$price_level	    Price level
2059
     * @param 	string		$selected		    Preselected value
2060
     * @param   int         $hidepriceinlabel   Hide price in label
2061
     * @return	void
2062
     */
2063
	private function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel=0)
2064
	{
2065
		global $langs,$conf,$user,$db;
2066
2067
        $outkey='';
2068
        $outval='';
2069
        $outref='';
2070
        $outlabel='';
2071
        $outdesc='';
2072
        $outbarcode='';
2073
        $outtype='';
2074
        $outprice_ht='';
2075
        $outprice_ttc='';
2076
        $outpricebasetype='';
2077
        $outtva_tx='';
2078
		$outqty=1;
2079
		$outdiscount=0;
2080
2081
		$maxlengtharticle=(empty($conf->global->PRODUCT_MAX_LENGTH_COMBO)?48:$conf->global->PRODUCT_MAX_LENGTH_COMBO);
2082
2083
        $label=$objp->label;
2084
        if (! empty($objp->label_translated)) $label=$objp->label_translated;
2085
        if (! empty($filterkey) && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1);
0 ignored issues
show
Bug introduced by
The variable $filterkey seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
2086
2087
        $outkey=$objp->rowid;
2088
        $outref=$objp->ref;
2089
        $outlabel=$objp->label;
2090
        $outdesc=$objp->description;
2091
        $outbarcode=$objp->barcode;
2092
2093
        $outtype=$objp->fk_product_type;
2094
        $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):'';
2095
        $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):'';
2096
2097
        $opt = '<option value="'.$objp->rowid.'"';
2098
        $opt.= ($objp->rowid == $selected)?' selected':'';
2099
		$opt.= (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)?' pbq="'.$objp->price_by_qty_rowid.'"':'';
2100
        if (! empty($conf->stock->enabled) && $objp->fk_product_type == 0 && isset($objp->stock))
2101
        {
2102
			if ($objp->stock > 0) $opt.= ' class="product_line_stock_ok"';
2103
			else if ($objp->stock <= 0) $opt.= ' class="product_line_stock_too_low"';
2104
        }
2105
        $opt.= '>';
2106
        $opt.= $objp->ref;
2107
        if ($outbarcode) $opt.=' ('.$outbarcode.')';
2108
        $opt.=' - '.dol_trunc($label,$maxlengtharticle);
2109
2110
        $objRef = $objp->ref;
2111
        if (! empty($filterkey) && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1);
2112
        $outval.=$objRef;
2113
        if ($outbarcode) $outval.=' ('.$outbarcode.')';
2114
        $outval.=' - '.dol_trunc($label,$maxlengtharticle);
2115
2116
        $found=0;
2117
2118
        // Multiprice
2119
        if (empty($hidepriceinlabel) && $price_level >= 1 && $conf->global->PRODUIT_MULTIPRICES)		// If we need a particular price level (from 1 to 6)
2120
        {
2121
            $sql = "SELECT price, price_ttc, price_base_type, tva_tx";
2122
            $sql.= " FROM ".MAIN_DB_PREFIX."product_price";
2123
            $sql.= " WHERE fk_product='".$objp->rowid."'";
2124
            $sql.= " AND entity IN (".getEntity('productprice', 1).")";
2125
            $sql.= " AND price_level=".$price_level;
2126
            $sql.= " ORDER BY date_price DESC, rowid DESC"; // Warning DESC must be both on date_price and rowid.
2127
            $sql.= " LIMIT 1";
2128
2129
            dol_syslog(get_class($this).'::constructProductListOption search price for level '.$price_level.'', LOG_DEBUG);
2130
            $result2 = $this->db->query($sql);
2131
            if ($result2)
2132
            {
2133
                $objp2 = $this->db->fetch_object($result2);
2134
                if ($objp2)
2135
                {
2136
                    $found=1;
2137
                    if ($objp2->price_base_type == 'HT')
2138
                    {
2139
                        $opt.= ' - '.price($objp2->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT");
2140
                        $outval.= ' - '.price($objp2->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT");
2141
                    }
2142
                    else
2143
                    {
2144
                        $opt.= ' - '.price($objp2->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC");
2145
                        $outval.= ' - '.price($objp2->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC");
2146
                    }
2147
                    $outprice_ht=price($objp2->price);
2148
                    $outprice_ttc=price($objp2->price_ttc);
2149
                    $outpricebasetype=$objp2->price_base_type;
2150
                    $outtva_tx=$objp2->tva_tx;
2151
                }
2152
            }
2153
            else
2154
            {
2155
                dol_print_error($this->db);
2156
            }
2157
        }
2158
2159
		// Price by quantity
2160
		if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1 && ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
2161
		{
2162
			$found = 1;
2163
			$outqty=$objp->quantity;
2164
			$outdiscount=$objp->remise_percent;
2165
			if ($objp->quantity == 1)
2166
			{
2167
				$opt.= ' - '.price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/";
2168
				$outval.= ' - '.price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/";
2169
				$opt.= $langs->trans("Unit");	// Do not use strtolower because it breaks utf8 encoding
2170
				$outval.=$langs->transnoentities("Unit");
2171
			}
2172
			else
2173
			{
2174
				$opt.= ' - '.price($objp->price,1,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2175
				$outval.= ' - '.price($objp->price,0,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2176
				$opt.= $langs->trans("Units");	// Do not use strtolower because it breaks utf8 encoding
2177
				$outval.=$langs->transnoentities("Units");
2178
			}
2179
2180
			$outprice_ht=price($objp->unitprice);
2181
            $outprice_ttc=price($objp->unitprice * (1 + ($objp->tva_tx / 100)));
2182
            $outpricebasetype=$objp->price_base_type;
2183
            $outtva_tx=$objp->tva_tx;
2184
		}
2185
		if (empty($hidepriceinlabel) && !empty($objp->quantity) && $objp->quantity >= 1)
2186
		{
2187
			$opt.=" (".price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2188
			$outval.=" (".price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/".$langs->transnoentities("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2189
		}
2190
		if (empty($hidepriceinlabel) && !empty($objp->remise_percent) && $objp->remise_percent >= 1)
2191
		{
2192
			$opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %';
2193
			$outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %';
2194
		}
2195
2196
		// Price by customer
2197
		if (empty($hidepriceinlabel) && !empty($conf->global->PRODUIT_CUSTOMER_PRICES))
2198
		{
2199
			if (!empty($objp->idprodcustprice))
2200
			{
2201
				$found = 1;
2202
2203
				if ($objp->custprice_base_type == 'HT')
2204
				{
2205
					$opt.= ' - '.price($objp->custprice,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT");
2206
					$outval.= ' - '.price($objp->custprice,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT");
2207
				}
2208
				else
2209
				{
2210
					$opt.= ' - '.price($objp->custprice_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC");
2211
					$outval.= ' - '.price($objp->custprice_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC");
2212
				}
2213
2214
				$outprice_ht=price($objp->custprice);
2215
				$outprice_ttc=price($objp->custprice_ttc);
2216
				$outpricebasetype=$objp->custprice_base_type;
2217
				$outtva_tx=$objp->custtva_tx;
2218
			}
2219
		}
2220
2221
        // If level no defined or multiprice not found, we used the default price
2222
        if (empty($hidepriceinlabel) && ! $found)
2223
        {
2224
            if ($objp->price_base_type == 'HT')
2225
            {
2226
                $opt.= ' - '.price($objp->price,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("HT");
2227
                $outval.= ' - '.price($objp->price,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("HT");
2228
            }
2229
            else
2230
            {
2231
                $opt.= ' - '.price($objp->price_ttc,1,$langs,0,0,-1,$conf->currency).' '.$langs->trans("TTC");
2232
                $outval.= ' - '.price($objp->price_ttc,0,$langs,0,0,-1,$conf->currency).' '.$langs->transnoentities("TTC");
2233
            }
2234
            $outprice_ht=price($objp->price);
2235
            $outprice_ttc=price($objp->price_ttc);
2236
            $outpricebasetype=$objp->price_base_type;
2237
            $outtva_tx=$objp->tva_tx;
2238
        }
2239
2240
        if (! empty($conf->stock->enabled) && isset($objp->stock) && $objp->fk_product_type == 0)
2241
        {
2242
            $opt.= ' - '.$langs->trans("Stock").':'.$objp->stock;
2243
2244
            if ($objp->stock > 0) {
2245
            	$outval.= ' - <span class="product_line_stock_ok">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>';
2246
            }elseif ($objp->stock <= 0) {
2247
            	$outval.= ' - <span class="product_line_stock_too_low">'.$langs->transnoentities("Stock").':'.$objp->stock.'</span>';
2248
            }
2249
        }
2250
2251
        if ($outdurationvalue && $outdurationunit)
2252
        {
2253
            $da=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year"));
2254
            if (isset($da[$outdurationunit]))
2255
            {
2256
                $key = $da[$outdurationunit].($outdurationvalue > 1?'s':'');
2257
                $opt.= ' - '.$outdurationvalue.' '.$langs->trans($key);
2258
                $outval.=' - '.$outdurationvalue.' '.$langs->transnoentities($key);
2259
            }
2260
        }
2261
2262
        $opt.= "</option>\n";
2263
		$optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit);
2264
	}
2265
2266
    /**
2267
     *	Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list)
2268
     *
2269
     *	@param	int		$socid			Id third party
2270
     *	@param  string	$selected       Preselected product
2271
     *	@param  string	$htmlname       Name of HTML Select
2272
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2273
     *	@param  string	$filtre			For a SQL filter
2274
     *	@param	array	$ajaxoptions	Options for ajax_autocompleter
2275
	 *  @param	int		$hidelabel		Hide label (0=no, 1=yes)
2276
	 *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2277
     *	@return	void
2278
     */
2279
    function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0, $alsoproductwithnosupplierprice=0)
2280
    {
2281
        global $langs,$conf;
2282
        global $price_level, $status, $finished;
2283
2284
        $selected_input_value='';
2285
        if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
2286
        {
2287
            if ($selected > 0)
2288
            {
2289
                require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
2290
                $producttmpselect = new Product($this->db);
2291
                $producttmpselect->fetch($selected);
2292
                $selected_input_value=$producttmpselect->ref;
2293
                unset($producttmpselect);
2294
            }
2295
2296
        	if (!empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED))
2297
			{
2298
				print '<input type="hidden" id="idprod" name="idprod" value="0" />';
2299
			}
2300
			// mode=2 means suppliers products
2301
            $urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished.'&alsoproductwithnosupplierprice='.$alsoproductwithnosupplierprice;
2302
            print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
2303
            print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').'<input type="text" size="20" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'">';
2304
        }
2305
        else
2306
        {
2307
            if (!empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED))
2308
			{
2309
				print '<input type="hidden" id="idprod" name="idprod" value="0" />';
2310
				print '<script type="text/javascript">$("#'.$htmlname.'").change(function() { $("#idprod").val($(this).val());});</script>';
2311
			}
2312
        	print $this->select_produits_fournisseurs_list($socid,$selected,$htmlname,$filtertype,$filtre,'',-1,0,0,$alsoproductwithnosupplierprice);
2313
        }
2314
    }
2315
2316
    /**
2317
     *	Return list of suppliers products
2318
     *
2319
     *	@param	int		$socid   		Id societe fournisseur (0 pour aucun filtre)
2320
     *	@param  int		$selected       Produit pre-selectionne
2321
     *	@param  string	$htmlname       Nom de la zone select
2322
     *  @param	string	$filtertype     Filter on product type (''=nofilter, 0=product, 1=service)
2323
     *	@param  string	$filtre         Pour filtre sql
2324
     *	@param  string	$filterkey      Filtre des produits
2325
     *  @param  int		$statut         -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request)
2326
     *  @param  int		$outputmode     0=HTML select string, 1=Array
2327
     *  @param  int     $limit          Limit of line number
2328
	 *  @param  int     $alsoproductwithnosupplierprice    1=Add also product without supplier prices
2329
     *  @return array           		Array of keys for json
2330
     */
2331
    function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100,$alsoproductwithnosupplierprice=0)
2332
    {
2333
        global $langs,$conf,$db;
2334
2335
        $out='';
2336
        $outarray=array();
2337
2338
        $langs->load('stocks');
2339
2340
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
2341
        $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
2342
        $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
2343
        $sql.= " pfp.supplier_reputation";
2344
        $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
2345
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2346
        if ($socid) $sql.= " AND pfp.fk_soc = ".$socid;
2347
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid";
2348
        $sql.= " WHERE p.entity IN (".getEntity('product', 1).")";
2349
        $sql.= " AND p.tobuy = 1";
2350
        if (strval($filtertype) != '') $sql.=" AND p.fk_product_type=".$this->db->escape($filtertype);
2351
        if (! empty($filtre)) $sql.=" ".$filtre;
2352
        // Add criteria on ref/label
2353
        if ($filterkey != '')
2354
        {
2355
        	$sql.=' AND (';
2356
        	$prefix=empty($conf->global->PRODUCT_DONOTSEARCH_ANYWHERE)?'%':'';	// Can use index if PRODUCT_DONOTSEARCH_ANYWHERE is on
2357
        	// For natural search
2358
        	$scrit = explode(' ', $filterkey);
2359
        	$i=0;
2360
        	if (count($scrit) > 1) $sql.="(";
2361
        	foreach ($scrit as $crit)
2362
        	{
2363
        		if ($i > 0) $sql.=" AND ";
2364
        		$sql.="(pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%' OR p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%')";
2365
        		$i++;
2366
        	}
2367
        	if (count($scrit) > 1) $sql.=")";
2368
        	if (! empty($conf->barcode->enabled)) $sql.= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'";
2369
        	$sql.=')';
2370
        }
2371
        $sql.= " ORDER BY pfp.ref_fourn DESC, pfp.quantity ASC";
2372
        $sql.= $db->plimit($limit);
2373
2374
        // Build output string
2375
2376
        dol_syslog(get_class($this)."::select_produits_fournisseurs_list", LOG_DEBUG);
2377
        $result=$this->db->query($sql);
2378
        if ($result)
2379
        {
2380
            require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
2381
2382
            $num = $this->db->num_rows($result);
2383
2384
            //$out.='<select class="flat" id="select'.$htmlname.'" name="'.$htmlname.'">';	// remove select to have id same with combo and ajax
2385
            $out.='<select class="flat maxwidthonsmartphone" id="'.$htmlname.'" name="'.$htmlname.'">';
2386
            if (! $selected) $out.='<option value="0" selected>&nbsp;</option>';
2387
            else $out.='<option value="0">&nbsp;</option>';
2388
2389
            $i = 0;
2390
            while ($i < $num)
2391
            {
2392
                $objp = $this->db->fetch_object($result);
2393
2394
                $outkey=$objp->idprodfournprice;                                                    // id in table of price
2395
                if (! $outkey && $alsoproductwithnosupplierprice) $outkey='idprod_'.$objp->rowid;   // id of product
2396
2397
                $outref=$objp->ref;
2398
                $outval='';
2399
                $outqty=1;
2400
				$outdiscount=0;
2401
                $outtype=$objp->fk_product_type;
2402
                $outdurationvalue=$outtype == Product::TYPE_SERVICE?substr($objp->duration,0,dol_strlen($objp->duration)-1):'';
2403
                $outdurationunit=$outtype == Product::TYPE_SERVICE?substr($objp->duration,-1):'';
2404
2405
                $opt = '<option value="'.$outkey.'"';
2406
                if ($selected && $selected == $objp->idprodfournprice) $opt.= ' selected';
2407
                if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt.=' disabled';
2408
                $opt.= '>';
2409
2410
                $objRef = $objp->ref;
2411
                if ($filterkey && $filterkey != '') $objRef=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRef,1);
2412
                $objRefFourn = $objp->ref_fourn;
2413
                if ($filterkey && $filterkey != '') $objRefFourn=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$objRefFourn,1);
2414
                $label = $objp->label;
2415
                if ($filterkey && $filterkey != '') $label=preg_replace('/('.preg_quote($filterkey).')/i','<strong>$1</strong>',$label,1);
2416
2417
                $opt.=$objp->ref;
2418
                if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2419
                	$opt.=' ('.$objp->ref_fourn.')';
2420
                $opt.=' - ';
2421
                $outval.=$objRef;
2422
                if (! empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
2423
                	$outval.=' ('.$objRefFourn.')';
2424
                $outval.=' - ';
2425
                $opt.=dol_trunc($label, 72).' - ';
2426
                $outval.=dol_trunc($label, 72).' - ';
2427
2428
                if (! empty($objp->idprodfournprice))
2429
                {
2430
                    $outqty=$objp->quantity;
2431
					$outdiscount=$objp->remise_percent;
2432
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2433
                        $prod_supplier = new ProductFournisseur($this->db);
2434
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2435
                        $prod_supplier->id = $objp->fk_product;
2436
                        $prod_supplier->fourn_qty = $objp->quantity;
2437
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2438
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2439
                        $priceparser = new PriceParser($this->db);
2440
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2441
                        if ($price_result >= 0) {
2442
                            $objp->fprice = $price_result;
2443
                            if ($objp->quantity >= 1)
2444
                            {
2445
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2446
                            }
2447
                        }
2448
                    }
2449
                    if ($objp->quantity == 1)
2450
                    {
2451
	                    $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/";
2452
                    	$outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/";
2453
                    	$opt.= $langs->trans("Unit");	// Do not use strtolower because it breaks utf8 encoding
2454
                        $outval.=$langs->transnoentities("Unit");
2455
                    }
2456
                    else
2457
                    {
2458
    	                $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2459
	                    $outval.= price($objp->fprice,0,$langs,0,0,-1,$conf->currency)."/".$objp->quantity;
2460
                    	$opt.= ' '.$langs->trans("Units");	// Do not use strtolower because it breaks utf8 encoding
2461
                        $outval.= ' '.$langs->transnoentities("Units");
2462
                    }
2463
2464
                    if ($objp->quantity >= 1)
2465
                    {
2466
                        $opt.=" (".price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2467
                        $outval.=" (".price($objp->unitprice,0,$langs,0,0,-1,$conf->currency)."/".$langs->transnoentities("Unit").")";	// Do not use strtolower because it breaks utf8 encoding
2468
                    }
2469
					if ($objp->remise_percent >= 1)
2470
                    {
2471
                        $opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %';
2472
                        $outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %';
2473
                    }
2474
                    if ($objp->duration)
2475
                    {
2476
                        $opt .= " - ".$objp->duration;
2477
                        $outval.=" - ".$objp->duration;
2478
                    }
2479
                    if (! $socid)
2480
                    {
2481
                        $opt .= " - ".dol_trunc($objp->name,8);
2482
                        $outval.=" - ".dol_trunc($objp->name,8);
2483
                    }
2484
                    if ($objp->supplier_reputation)
2485
                    {
2486
            			//TODO dictionnary
2487
            			$reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier'));
2488
2489
                        $opt .= " - ".$reputations[$objp->supplier_reputation];
2490
                        $outval.=" - ".$reputations[$objp->supplier_reputation];
2491
                    }
2492
                }
2493
                else
2494
                {
2495
                    if (empty($alsoproductwithnosupplierprice))     // No supplier price defined for couple product/supplier
2496
                    {
2497
                        $opt.= $langs->trans("NoPriceDefinedForThisSupplier");
2498
                        $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
2499
                    }
2500
                    else                                            // No supplier price defined for product, even on other suppliers
2501
                    {
2502
                        $opt.= $langs->trans("NoPriceDefinedForThisSupplier");
2503
                        $outval.=$langs->transnoentities("NoPriceDefinedForThisSupplier");
2504
                    }
2505
                }
2506
                $opt .= "</option>\n";
2507
2508
2509
                // Add new entry
2510
                // "key" value of json key array is used by jQuery automatically as selected value
2511
                // "label" value of json key array is used by jQuery automatically as text for combo box
2512
                $out.=$opt;
2513
                array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice)?true:false)));
2514
				// Exemple of var_dump $outarray
2515
				// array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp"
2516
				//           ["label"]=>string(76) "ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)"
2517
				//      	 ["qty"]=>string(1) "1" ["discount"]=>string(1) "0" ["disabled"]=>bool(false)
2518
                //}
2519
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2520
                //$outval=array('label'=>'ppp (<strong>f</strong>ff2) - ppp - 20,00 Euros/ Unité (20,00 Euros/unité)');
2521
                //var_dump($outval); var_dump(utf8_check($outval)); var_dump(json_encode($outval));
2522
2523
                $i++;
2524
            }
2525
            $out.='</select>';
2526
2527
            $this->db->free($result);
2528
2529
            if (empty($outputmode)) return $out;
2530
            return $outarray;
2531
        }
2532
        else
2533
        {
2534
            dol_print_error($this->db);
2535
        }
2536
    }
2537
2538
    /**
2539
     *	Return list of suppliers prices for a product
2540
     *
2541
     *  @param	    int		$productid       	Id of product
2542
     *  @param      string	$htmlname        	Name of HTML field
2543
     *  @param      int		$selected_supplier  Pre-selected supplier if more than 1 result
2544
     *  @return	    void
2545
     */
2546
    function select_product_fourn_price($productid, $htmlname='productfournpriceid', $selected_supplier='')
2547
    {
2548
        global $langs,$conf;
2549
2550
        $langs->load('stocks');
2551
2552
        $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,";
2553
        $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice,";
2554
        $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name";
2555
        $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
2556
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
2557
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON pfp.fk_soc = s.rowid";
2558
        $sql.= " WHERE p.entity IN (".getEntity('productprice', 1).")";
2559
        $sql.= " AND p.tobuy = 1";
2560
        $sql.= " AND s.fournisseur = 1";
2561
        $sql.= " AND p.rowid = ".$productid;
2562
        $sql.= " ORDER BY s.nom, pfp.ref_fourn DESC";
2563
2564
        dol_syslog(get_class($this)."::select_product_fourn_price", LOG_DEBUG);
2565
        $result=$this->db->query($sql);
2566
2567
        if ($result)
2568
        {
2569
            $num = $this->db->num_rows($result);
2570
2571
            $form = '<select class="flat" name="'.$htmlname.'">';
2572
2573
            if (! $num)
2574
            {
2575
                $form.= '<option value="0">-- '.$langs->trans("NoSupplierPriceDefinedForThisProduct").' --</option>';
2576
            }
2577
            else
2578
            {
2579
                require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
2580
                $form.= '<option value="0">&nbsp;</option>';
2581
2582
                $i = 0;
2583
                while ($i < $num)
2584
                {
2585
                    $objp = $this->db->fetch_object($result);
2586
2587
                    $opt = '<option value="'.$objp->idprodfournprice.'"';
2588
                    //if there is only one supplier, preselect it
2589
                    if($num == 1 || ($selected_supplier > 0 && $objp->fk_soc == $selected_supplier)) {
2590
                        $opt .= ' selected';
2591
                    }
2592
                    $opt.= '>'.$objp->name.' - '.$objp->ref_fourn.' - ';
2593
2594
                    if (!empty($conf->dynamicprices->enabled) && !empty($objp->fk_supplier_price_expression)) {
2595
                        $prod_supplier = new ProductFournisseur($this->db);
2596
                        $prod_supplier->product_fourn_price_id = $objp->idprodfournprice;
2597
                        $prod_supplier->id = $productid;
2598
                        $prod_supplier->fourn_qty = $objp->quantity;
2599
                        $prod_supplier->fourn_tva_tx = $objp->tva_tx;
2600
                        $prod_supplier->fk_supplier_price_expression = $objp->fk_supplier_price_expression;
2601
                        $priceparser = new PriceParser($this->db);
2602
                        $price_result = $priceparser->parseProductSupplier($prod_supplier);
2603
                        if ($price_result >= 0) {
2604
                            $objp->fprice = $price_result;
2605
                            if ($objp->quantity >= 1)
2606
                            {
2607
                                $objp->unitprice = $objp->fprice / $objp->quantity;
2608
                            }
2609
                        }
2610
                    }
2611
                    if ($objp->quantity == 1)
2612
                    {
2613
                        $opt.= price($objp->fprice,1,$langs,0,0,-1,$conf->currency)."/";
2614
                    }
2615
2616
                    $opt.= $objp->quantity.' ';
2617
2618
                    if ($objp->quantity == 1)
2619
                    {
2620
                        $opt.= $langs->trans("Unit");
2621
                    }
2622
                    else
2623
                    {
2624
                        $opt.= $langs->trans("Units");
2625
                    }
2626
                    if ($objp->quantity > 1)
2627
                    {
2628
                        $opt.=" - ";
2629
                        $opt.= price($objp->unitprice,1,$langs,0,0,-1,$conf->currency)."/".$langs->trans("Unit");
2630
                    }
2631
                    if ($objp->duration) $opt .= " - ".$objp->duration;
2632
                    $opt .= "</option>\n";
2633
2634
                    $form.= $opt;
2635
                    $i++;
2636
                }
2637
            }
2638
2639
            $form.= '</select>';
2640
            $this->db->free($result);
2641
            return $form;
2642
        }
2643
        else
2644
        {
2645
            dol_print_error($this->db);
2646
        }
2647
    }
2648
2649
    /**
2650
     *    Return list of delivery address
2651
     *
2652
     *    @param    string	$selected          	Id contact pre-selectionn
2653
     *    @param    int		$socid				Id of company
2654
     *    @param    string	$htmlname          	Name of HTML field
2655
     *    @param    int		$showempty         	Add an empty field
2656
     *    @return	integer|null
2657
     */
2658
    function select_address($selected, $socid, $htmlname='address_id',$showempty=0)
2659
    {
2660
        // On recherche les utilisateurs
2661
        $sql = "SELECT a.rowid, a.label";
2662
        $sql .= " FROM ".MAIN_DB_PREFIX ."societe_address as a";
2663
        $sql .= " WHERE a.fk_soc = ".$socid;
2664
        $sql .= " ORDER BY a.label ASC";
2665
2666
        dol_syslog(get_class($this)."::select_address", LOG_DEBUG);
2667
        $resql=$this->db->query($sql);
2668
        if ($resql)
2669
        {
2670
            print '<select class="flat" name="'.$htmlname.'">';
2671
            if ($showempty) print '<option value="0">&nbsp;</option>';
2672
            $num = $this->db->num_rows($resql);
2673
            $i = 0;
2674
            if ($num)
2675
            {
2676
                while ($i < $num)
2677
                {
2678
                    $obj = $this->db->fetch_object($resql);
2679
2680
                    if ($selected && $selected == $obj->rowid)
2681
                    {
2682
                        print '<option value="'.$obj->rowid.'" selected>'.$obj->label.'</option>';
2683
                    }
2684
                    else
2685
                    {
2686
                        print '<option value="'.$obj->rowid.'">'.$obj->label.'</option>';
2687
                    }
2688
                    $i++;
2689
                }
2690
            }
2691
            print '</select>';
2692
            return $num;
2693
        }
2694
        else
2695
        {
2696
            dol_print_error($this->db);
2697
        }
2698
    }
2699
2700
2701
    /**
2702
     *      Load into cache list of payment terms
2703
     *
2704
     *      @return     int             Nb of lines loaded, <0 if KO
2705
     */
2706
    function load_cache_conditions_paiements()
2707
    {
2708
        global $langs;
2709
2710
        $num = count($this->cache_conditions_paiements);
2711
        if ($num > 0) return 0;    // Cache already loaded
2712
2713
        dol_syslog(__METHOD__, LOG_DEBUG);
2714
2715
        $sql = "SELECT rowid, code, libelle as label";
2716
        $sql.= " FROM ".MAIN_DB_PREFIX.'c_payment_term';
2717
        $sql.= " WHERE active > 0";
2718
        $sql.= " ORDER BY sortorder";
2719
2720
        $resql = $this->db->query($sql);
2721
        if ($resql)
2722
        {
2723
            $num = $this->db->num_rows($resql);
2724
            $i = 0;
2725
            while ($i < $num)
2726
            {
2727
                $obj = $this->db->fetch_object($resql);
2728
2729
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2730
                $label=($langs->trans("PaymentConditionShort".$obj->code)!=("PaymentConditionShort".$obj->code)?$langs->trans("PaymentConditionShort".$obj->code):($obj->label!='-'?$obj->label:''));
2731
                $this->cache_conditions_paiements[$obj->rowid]['code'] =$obj->code;
2732
                $this->cache_conditions_paiements[$obj->rowid]['label']=$label;
2733
                $i++;
2734
            }
2735
2736
			//$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label', 'asc', 0, 0, 1);		// We use the field sortorder of table
2737
2738
            return $num;
2739
        }
2740
        else
2741
		{
2742
            dol_print_error($this->db);
2743
            return -1;
2744
        }
2745
    }
2746
2747
    /**
2748
     *      Charge dans cache la liste des délais de livraison possibles
2749
     *
2750
     *      @return     int             Nb of lines loaded, <0 if KO
2751
     */
2752
    function load_cache_availability()
2753
    {
2754
        global $langs;
2755
2756
        $num = count($this->cache_availability);
2757
        if ($num > 0) return 0;    // Cache already loaded
2758
2759
        dol_syslog(__METHOD__, LOG_DEBUG);
2760
2761
		$langs->load('propal');
2762
2763
        $sql = "SELECT rowid, code, label";
2764
        $sql.= " FROM ".MAIN_DB_PREFIX.'c_availability';
2765
        $sql.= " WHERE active > 0";
2766
2767
        $resql = $this->db->query($sql);
2768
        if ($resql)
2769
        {
2770
            $num = $this->db->num_rows($resql);
2771
            $i = 0;
2772
            while ($i < $num)
2773
            {
2774
                $obj = $this->db->fetch_object($resql);
2775
2776
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2777
                $label=($langs->trans("AvailabilityType".$obj->code)!=("AvailabilityType".$obj->code)?$langs->trans("AvailabilityType".$obj->code):($obj->label!='-'?$obj->label:''));
2778
                $this->cache_availability[$obj->rowid]['code'] =$obj->code;
2779
                $this->cache_availability[$obj->rowid]['label']=$label;
2780
                $i++;
2781
            }
2782
2783
            $this->cache_availability = dol_sort_array($this->cache_availability, 'label', 'asc', 0, 0, 1);
2784
2785
            return $num;
2786
        }
2787
        else
2788
		{
2789
            dol_print_error($this->db);
2790
            return -1;
2791
        }
2792
    }
2793
2794
    /**
2795
     *      Retourne la liste des types de delais de livraison possibles
2796
     *
2797
     *      @param	int		$selected        Id du type de delais pre-selectionne
2798
     *      @param  string	$htmlname        Nom de la zone select
2799
     *      @param  string	$filtertype      To add a filter
2800
     *		@param	int		$addempty		Add empty entry
2801
     *		@return	void
2802
     */
2803
    function selectAvailabilityDelay($selected='',$htmlname='availid',$filtertype='',$addempty=0)
2804
    {
2805
        global $langs,$user;
2806
2807
        $this->load_cache_availability();
2808
2809
        dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
2810
2811
        print '<select class="flat" name="'.$htmlname.'">';
2812
        if ($addempty) print '<option value="0">&nbsp;</option>';
2813
        foreach($this->cache_availability as $id => $arrayavailability)
2814
        {
2815
            if ($selected == $id)
2816
            {
2817
                print '<option value="'.$id.'" selected>';
2818
            }
2819
            else
2820
            {
2821
                print '<option value="'.$id.'">';
2822
            }
2823
            print $arrayavailability['label'];
2824
            print '</option>';
2825
        }
2826
        print '</select>';
2827
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
2828
    }
2829
2830
    /**
2831
     *      Load into cache cache_demand_reason, array of input reasons
2832
     *
2833
     *      @return     int             Nb of lines loaded, <0 if KO
2834
     */
2835
    function loadCacheInputReason()
2836
    {
2837
        global $langs;
2838
2839
        $num = count($this->cache_demand_reason);
2840
        if ($num > 0) return 0;    // Cache already loaded
2841
2842
        $sql = "SELECT rowid, code, label";
2843
        $sql.= " FROM ".MAIN_DB_PREFIX.'c_input_reason';
2844
        $sql.= " WHERE active > 0";
2845
2846
        $resql = $this->db->query($sql);
2847
        if ($resql)
2848
        {
2849
            $num = $this->db->num_rows($resql);
2850
            $i = 0;
2851
            $tmparray=array();
2852
            while ($i < $num)
2853
            {
2854
                $obj = $this->db->fetch_object($resql);
2855
2856
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2857
                $label=($langs->trans("DemandReasonType".$obj->code)!=("DemandReasonType".$obj->code)?$langs->trans("DemandReasonType".$obj->code):($obj->label!='-'?$obj->label:''));
2858
                $tmparray[$obj->rowid]['id']   =$obj->rowid;
2859
                $tmparray[$obj->rowid]['code'] =$obj->code;
2860
                $tmparray[$obj->rowid]['label']=$label;
2861
                $i++;
2862
            }
2863
2864
            $this->cache_demand_reason=dol_sort_array($tmparray, 'label', 'asc', 0, 0, 1);
2865
2866
            unset($tmparray);
2867
            return $num;
2868
        }
2869
        else
2870
		{
2871
            dol_print_error($this->db);
2872
            return -1;
2873
        }
2874
    }
2875
2876
    /**
2877
	 *	Return list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
2878
	 *  List found into table c_input_reason loaded by loadCacheInputReason
2879
     *
2880
     *  @param	int		$selected        Id or code of type origin to select by default
2881
     *  @param  string	$htmlname        Nom de la zone select
2882
     *  @param  string	$exclude         To exclude a code value (Example: SRC_PROP)
2883
     *	@param	int		$addempty		 Add an empty entry
2884
     *	@return	void
2885
     */
2886
    function selectInputReason($selected='',$htmlname='demandreasonid',$exclude='',$addempty=0)
2887
    {
2888
        global $langs,$user;
2889
2890
        $this->loadCacheInputReason();
2891
2892
        print '<select class="flat" name="'.$htmlname.'">';
2893
        if ($addempty) print '<option value="0"'.(empty($selected)?' selected':'').'>&nbsp;</option>';
2894
        foreach($this->cache_demand_reason as $id => $arraydemandreason)
2895
        {
2896
            if ($arraydemandreason['code']==$exclude) continue;
2897
2898
            if ($selected && ($selected == $arraydemandreason['id'] || $selected == $arraydemandreason['code']))
2899
            {
2900
                print '<option value="'.$arraydemandreason['id'].'" selected>';
2901
            }
2902
            else
2903
            {
2904
                print '<option value="'.$arraydemandreason['id'].'">';
2905
            }
2906
            print $arraydemandreason['label'];
2907
            print '</option>';
2908
        }
2909
        print '</select>';
2910
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
2911
    }
2912
2913
    /**
2914
     *      Charge dans cache la liste des types de paiements possibles
2915
     *
2916
     *      @return     int                 Nb of lines loaded, <0 if KO
2917
     */
2918
    function load_cache_types_paiements()
2919
    {
2920
        global $langs;
2921
2922
        $num=count($this->cache_types_paiements);
2923
        if ($num > 0) return $num;    // Cache already loaded
2924
2925
        dol_syslog(__METHOD__, LOG_DEBUG);
2926
2927
        $this->cache_types_paiements = array();
2928
2929
        $sql = "SELECT id, code, libelle as label, type, active";
2930
        $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement";
2931
        //if ($active >= 0) $sql.= " WHERE active = ".$active;
2932
2933
        $resql = $this->db->query($sql);
2934
        if ($resql)
2935
        {
2936
            $num = $this->db->num_rows($resql);
2937
            $i = 0;
2938
            while ($i < $num)
2939
            {
2940
                $obj = $this->db->fetch_object($resql);
2941
2942
                // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
2943
                $label=($langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code)!=("PaymentTypeShort".$obj->code)?$langs->transnoentitiesnoconv("PaymentTypeShort".$obj->code):($obj->label!='-'?$obj->label:''));
2944
                $this->cache_types_paiements[$obj->id]['id'] =$obj->id;
2945
                $this->cache_types_paiements[$obj->id]['code'] =$obj->code;
2946
                $this->cache_types_paiements[$obj->id]['label']=$label;
2947
                $this->cache_types_paiements[$obj->id]['type'] =$obj->type;
2948
                $this->cache_types_paiements[$obj->id]['active'] =$obj->active;
2949
                $i++;
2950
            }
2951
2952
            $this->cache_types_paiements = dol_sort_array($this->cache_types_paiements, 'label', 'asc', 0, 0, 1);
2953
2954
            return $num;
2955
        }
2956
        else
2957
		{
2958
            dol_print_error($this->db);
2959
            return -1;
2960
        }
2961
    }
2962
2963
2964
    /**
2965
     *      Return list of payment modes.
2966
     *      Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want.
2967
     *      See instead to force the default value by the caller.
2968
     *
2969
     *      @param	int  	$selected        Id of payment term to preselect by default
2970
     *      @param  string	$htmlname        Nom de la zone select
2971
     *      @param  int 	$filtertype      Not used
2972
     *		@param	int		$addempty		 Add an empty entry
2973
     *		@return	void
2974
     */
2975
    function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0)
2976
    {
2977
        global $langs, $user, $conf;
2978
2979
        dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
2980
2981
        $this->load_cache_conditions_paiements();
2982
2983
        // Set default value if not already set by caller
2984
        if (empty($selected) && ! empty($conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID;
2985
2986
        print '<select class="flat" name="'.$htmlname.'">';
2987
        if ($addempty) print '<option value="0">&nbsp;</option>';
2988
        foreach($this->cache_conditions_paiements as $id => $arrayconditions)
2989
        {
2990
            if ($selected == $id)
2991
            {
2992
                print '<option value="'.$id.'" selected>';
2993
            }
2994
            else
2995
            {
2996
                print '<option value="'.$id.'">';
2997
            }
2998
            print $arrayconditions['label'];
2999
            print '</option>';
3000
        }
3001
        print '</select>';
3002
        if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
3003
    }
3004
3005
3006
    /**
3007
     *      Return list of payment methods
3008
     *
3009
     *      @param	string	$selected       Id du mode de paiement pre-selectionne
3010
     *      @param  string	$htmlname       Nom de la zone select
3011
     *      @param  string	$filtertype     To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz))
3012
     *      @param  int		$format         0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code
3013
     *      @param  int		$empty			1=peut etre vide, 0 sinon
3014
     * 		@param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
3015
     *      @param  int		$maxlength      Max length of label
3016
     *      @param  int     $active         Active or not, -1 = all
3017
     *      @param  string  $morecss        Add more css
3018
     * 		@return	void
3019
     */
3020
    function select_types_paiements($selected='', $htmlname='paiementtype', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $active=1, $morecss='')
3021
    {
3022
        global $langs,$user;
3023
3024
        dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
3025
3026
        $filterarray=array();
3027
        if ($filtertype == 'CRDT')  	$filterarray=array(0,2,3);
3028
        elseif ($filtertype == 'DBIT') 	$filterarray=array(1,2,3);
3029
        elseif ($filtertype != '' && $filtertype != '-1') $filterarray=explode(',',$filtertype);
3030
3031
        $this->load_cache_types_paiements();
3032
3033
        print '<select id="select'.$htmlname.'" class="flat selectpaymenttypes'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'">';
3034
        if ($empty) print '<option value="">&nbsp;</option>';
3035
        foreach($this->cache_types_paiements as $id => $arraytypes)
3036
        {
3037
            // If not good status
3038
            if ($active >= 0 && $arraytypes['active'] != $active) continue;
3039
3040
            // On passe si on a demande de filtrer sur des modes de paiments particuliers
3041
            if (count($filterarray) && ! in_array($arraytypes['type'],$filterarray)) continue;
3042
3043
            // We discard empty line if showempty is on because an empty line has already been output.
3044
            if ($empty && empty($arraytypes['code'])) continue;
3045
3046
            if ($format == 0) print '<option value="'.$id.'"';
3047
            if ($format == 1) print '<option value="'.$arraytypes['code'].'"';
3048
            if ($format == 2) print '<option value="'.$arraytypes['code'].'"';
3049
            if ($format == 3) print '<option value="'.$id.'"';
3050
            // Si selected est text, on compare avec code, sinon avec id
3051
            if (preg_match('/[a-z]/i', $selected) && $selected == $arraytypes['code']) print ' selected';
3052
            elseif ($selected == $id) print ' selected';
3053
            print '>';
3054
            if ($format == 0) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']);
3055
            if ($format == 1) $value=$arraytypes['code'];
3056
            if ($format == 2) $value=($maxlength?dol_trunc($arraytypes['label'],$maxlength):$arraytypes['label']);
3057
            if ($format == 3) $value=$arraytypes['code'];
3058
            print $value?$value:'&nbsp;';
0 ignored issues
show
Bug introduced by
The variable $value 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...
3059
            print '</option>';
3060
        }
3061
        print '</select>';
3062
        if ($user->admin && ! $noadmininfo) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
3063
    }
3064
3065
3066
    /**
3067
     *  Selection HT or TTC
3068
     *
3069
     *  @param	string	$selected       Id pre-selectionne
3070
     *  @param  string	$htmlname       Nom de la zone select
3071
     * 	@return	string					Code of HTML select to chose tax or not
3072
     */
3073
    function selectPriceBaseType($selected='',$htmlname='price_base_type')
3074
    {
3075
        global $langs;
3076
3077
        $return='';
3078
3079
        $return.= '<select class="flat" name="'.$htmlname.'">';
3080
        $options = array(
3081
			'HT'=>$langs->trans("HT"),
3082
			'TTC'=>$langs->trans("TTC")
3083
        );
3084
        foreach($options as $id => $value)
3085
        {
3086
            if ($selected == $id)
3087
            {
3088
                $return.= '<option value="'.$id.'" selected>'.$value;
3089
            }
3090
            else
3091
            {
3092
                $return.= '<option value="'.$id.'">'.$value;
3093
            }
3094
            $return.= '</option>';
3095
        }
3096
        $return.= '</select>';
3097
3098
        return $return;
3099
    }
3100
3101
    /**
3102
     *  Return a HTML select list of shipping mode
3103
     *
3104
     *  @param	string	$selected          Id shipping mode pre-selected
3105
     *  @param  string	$htmlname          Name of select zone
3106
     *  @param  string	$filtre            To filter list
3107
     *  @param  int		$useempty          1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3108
     *  @param  string	$moreattrib        To add more attribute on select
3109
     * 	@return	void
3110
     */
3111
    function selectShippingMethod($selected='',$htmlname='shipping_method_id',$filtre='',$useempty=0,$moreattrib='')
3112
    {
3113
        global $langs, $conf, $user;
3114
3115
        $langs->load("admin");
3116
        $langs->load("deliveries");
3117
3118
        $sql = "SELECT rowid, code, libelle as label";
3119
        $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode";
3120
        $sql.= " WHERE active > 0";
3121
        if ($filtre) $sql.=" AND ".$filtre;
3122
        $sql.= " ORDER BY libelle ASC";
3123
3124
        dol_syslog(get_class($this)."::selectShippingMode", LOG_DEBUG);
3125
        $result = $this->db->query($sql);
3126
        if ($result) {
3127
            $num = $this->db->num_rows($result);
3128
            $i = 0;
3129
            if ($num) {
3130
                print '<select id="select'.$htmlname.'" class="flat selectshippingmethod" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>';
3131
                if ($useempty == 1 || ($useempty == 2 && $num > 1)) {
3132
                    print '<option value="-1">&nbsp;</option>';
3133
                }
3134
                while ($i < $num) {
3135
                    $obj = $this->db->fetch_object($result);
3136
                    if ($selected == $obj->rowid) {
3137
                        print '<option value="'.$obj->rowid.'" selected>';
3138
                    } else {
3139
                        print '<option value="'.$obj->rowid.'">';
3140
                    }
3141
                    print ($langs->trans("SendingMethod".strtoupper($obj->code)) != "SendingMethod".strtoupper($obj->code)) ? $langs->trans("SendingMethod".strtoupper($obj->code)) : $obj->label;
3142
                    print '</option>';
3143
                    $i++;
3144
                }
3145
                print "</select>";
3146
                if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
3147
            } else {
3148
                print $langs->trans("NoShippingMethodDefined");
3149
            }
3150
        } else {
3151
            dol_print_error($this->db);
3152
        }
3153
    }
3154
3155
    /**
3156
     *    Display form to select shipping mode
3157
     *
3158
     *    @param	string	$page        Page
3159
     *    @param    int		$selected    Id of shipping mode
3160
     *    @param    string	$htmlname    Name of select html field
3161
     *    @param    int		$addempty    1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3162
     *    @return	void
3163
     */
3164
    function formSelectShippingMethod($page, $selected='', $htmlname='shipping_method_id', $addempty=0)
3165
    {
3166
        global $langs, $db;
3167
3168
        $langs->load("deliveries");
3169
3170
        if ($htmlname != "none") {
3171
            print '<form method="POST" action="'.$page.'">';
3172
            print '<input type="hidden" name="action" value="setshippingmethod">';
3173
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3174
            $this->selectShippingMethod($selected, $htmlname, '', $addempty);
3175
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3176
            print '</form>';
3177
        } else {
3178
            if ($selected) {
3179
                $code=$langs->getLabelFromKey($db, $selected, 'c_shipment_mode', 'rowid', 'code');
3180
                print $langs->trans("SendingMethod".strtoupper($code));
3181
            } else {
3182
                print "&nbsp;";
3183
            }
3184
        }
3185
    }
3186
3187
	/**
3188
	 * Creates HTML last in cycle situation invoices selector
3189
	 *
3190
	 * @param     string  $selected   		Preselected ID
3191
	 * @param     int     $socid      		Company ID
3192
	 *
3193
	 * @return    string                     HTML select
3194
	 */
3195
	function selectSituationInvoices($selected = '', $socid = 0)
3196
	{
3197
		global $langs;
3198
3199
		$langs->load('bills');
3200
3201
		$opt = '<option value ="" selected></option>';
3202
		$sql = 'SELECT rowid, facnumber, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1';
3203
		$sql.= ' ORDER by situation_cycle_ref, situation_counter desc';
3204
		$resql = $this->db->query($sql);
3205
		if ($resql && $this->db->num_rows($resql) > 0) {
3206
			// Last seen cycle
3207
			$ref = 0;
3208
			while ($res = $this->db->fetch_array($resql, MYSQL_NUM)) {
3209
				//Same company ?
3210
				if ($socid == $res[5]) {
3211
					//Same cycle ?
3212
					if ($res[2] != $ref) {
3213
						// Just seen this cycle
3214
						$ref = $res[2];
3215
						//not final ?
3216
						if ($res[4] != 1) {
3217
							//Not prov?
3218
							if (substr($res[1], 1, 4) != 'PROV') {
3219
								if ($selected == $res[0]) {
3220
									$opt .= '<option value="' . $res[0] . '" selected>' . $res[1] . '</option>';
3221
								} else {
3222
									$opt .= '<option value="' . $res[0] . '">' . $res[1] . '</option>';
3223
								}
3224
							}
3225
						}
3226
					}
3227
				}
3228
			}
3229
		}
3230
		else
3231
		{
3232
				dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
3233
		}
3234
		if ($opt == '<option value ="" selected></option>')
3235
		{
3236
			$opt = '<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>';
3237
		}
3238
		return $opt;
3239
	}
3240
3241
    /**
3242
     *      Creates HTML units selector (code => label)
3243
     *
3244
     *      @param	string	$selected       Preselected Unit ID
3245
     *      @param  string	$htmlname       Select name
3246
     *      @param	int		$showempty		Add a nempty line
3247
     * 		@return	string                  HTML select
3248
     */
3249
    function selectUnits($selected = '', $htmlname = 'units', $showempty=0)
3250
    {
3251
        global $langs;
3252
3253
        $langs->load('products');
3254
3255
        $return= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'">';
3256
3257
        $sql = 'SELECT rowid, label from '.MAIN_DB_PREFIX.'c_units';
3258
        $sql.= ' WHERE active > 0';
3259
3260
        $resql = $this->db->query($sql);
3261
        if($resql && $this->db->num_rows($resql) > 0)
3262
        {
3263
	        if ($showempty) $return .= '<option value="none"></option>';
3264
3265
            while($res = $this->db->fetch_object($resql))
3266
            {
3267
                if ($selected == $res->rowid)
3268
                {
3269
                    $return.='<option value="'.$res->rowid.'" selected>'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>';
3270
                }
3271
                else
3272
                {
3273
                    $return.='<option value="'.$res->rowid.'">'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>';
3274
                }
3275
            }
3276
            $return.='</select>';
3277
        }
3278
        return $return;
3279
    }
3280
3281
    /**
3282
     *  Return a HTML select list of bank accounts
3283
     *
3284
     *  @param	string	$selected          Id account pre-selected
3285
     *  @param  string	$htmlname          Name of select zone
3286
     *  @param  int		$statut            Status of searched accounts (0=open, 1=closed, 2=both)
3287
     *  @param  string	$filtre            To filter list
3288
     *  @param  int		$useempty          1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3289
     *  @param  string	$moreattrib        To add more attribute on select
3290
     * 	@return	void
3291
     */
3292
    function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='')
3293
    {
3294
        global $langs, $conf;
3295
3296
        $langs->load("admin");
3297
3298
        $sql = "SELECT rowid, label, bank, clos as status";
3299
        $sql.= " FROM ".MAIN_DB_PREFIX."bank_account";
3300
        $sql.= " WHERE entity IN (".getEntity('bank_account', 1).")";
3301
        if ($statut != 2) $sql.= " AND clos = '".$statut."'";
3302
        if ($filtre) $sql.=" AND ".$filtre;
3303
        $sql.= " ORDER BY label";
3304
3305
        dol_syslog(get_class($this)."::select_comptes", LOG_DEBUG);
3306
        $result = $this->db->query($sql);
3307
        if ($result)
3308
        {
3309
            $num = $this->db->num_rows($result);
3310
            $i = 0;
3311
            if ($num)
3312
            {
3313
                print '<select id="select'.$htmlname.'" class="flat selectbankaccount" name="'.$htmlname.'"'.($moreattrib?' '.$moreattrib:'').'>';
3314
                if ($useempty == 1 || ($useempty == 2 && $num > 1))
3315
                {
3316
                    print '<option value="-1">&nbsp;</option>';
3317
                }
3318
3319
                while ($i < $num)
3320
                {
3321
                    $obj = $this->db->fetch_object($result);
3322
                    if ($selected == $obj->rowid)
3323
                    {
3324
                        print '<option value="'.$obj->rowid.'" selected>';
3325
                    }
3326
                    else
3327
                    {
3328
                        print '<option value="'.$obj->rowid.'">';
3329
                    }
3330
                    print trim($obj->label);
3331
                    if ($statut == 2 && $obj->status == 1) print ' ('.$langs->trans("Closed").')';
3332
                    print '</option>';
3333
                    $i++;
3334
                }
3335
                print "</select>";
3336
            }
3337
            else
3338
            {
3339
                print $langs->trans("NoActiveBankAccountDefined");
3340
            }
3341
        }
3342
        else {
3343
            dol_print_error($this->db);
3344
        }
3345
    }
3346
3347
    /**
3348
     *    Display form to select bank account
3349
     *
3350
     *    @param	string	$page        Page
3351
     *    @param    int		$selected    Id of bank account
3352
     *    @param    string	$htmlname    Name of select html field
3353
     *    @param    int		$addempty    1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries.
3354
     *    @return	void
3355
     */
3356
    function formSelectAccount($page, $selected='', $htmlname='fk_account', $addempty=0)
3357
    {
3358
        global $langs;
3359
        if ($htmlname != "none") {
3360
            print '<form method="POST" action="'.$page.'">';
3361
            print '<input type="hidden" name="action" value="setbankaccount">';
3362
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3363
            $this->select_comptes($selected, $htmlname, 0, '', $addempty);
3364
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3365
            print '</form>';
3366
        } else {
3367
            if ($selected) {
3368
                require_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php';
3369
                $bankstatic=new Account($this->db);
3370
                $bankstatic->fetch($selected);
3371
                print $this->textwithpicto($bankstatic->label,$langs->trans("AccountCurrency").'&nbsp;'.$bankstatic->currency_code);
3372
            } else {
3373
                print "&nbsp;";
3374
            }
3375
        }
3376
    }
3377
3378
    /**
3379
     *    Return list of categories having choosed type
3380
     *
3381
     *    @param	int		$type				Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated.
3382
     *    @param    string	$selected    		Id of category preselected or 'auto' (autoselect category if there is only one element)
3383
     *    @param    string	$htmlname			HTML field name
3384
     *    @param    int		$maxlength      	Maximum length for labels
3385
     *    @param    int		$excludeafterid 	Exclude all categories after this leaf in category tree.
3386
     *    @param	int		$outputmode			0=HTML select string, 1=Array
3387
     *    @return	string
3388
     *    @see select_categories
3389
     */
3390
    function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0)
3391
    {
3392
        global $langs;
3393
        $langs->load("categories");
3394
3395
		include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
3396
3397
		// For backward compatibility
3398
		if (is_numeric($type))
3399
		{
3400
		    dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING);
3401
		}
3402
3403
        $cat = new Categorie($this->db);
3404
        $cate_arbo = $cat->get_full_arbo($type,$excludeafterid);
3405
3406
        $output = '<select class="flat" name="'.$htmlname.'">';
3407
		$outarray=array();
3408
        if (is_array($cate_arbo))
3409
        {
3410
            if (! count($cate_arbo)) $output.= '<option value="-1" disabled>'.$langs->trans("NoCategoriesDefined").'</option>';
3411
            else
3412
            {
3413
                $output.= '<option value="-1">&nbsp;</option>';
3414
                foreach($cate_arbo as $key => $value)
3415
                {
3416
                    if ($cate_arbo[$key]['id'] == $selected || ($selected == 'auto' && count($cate_arbo) == 1))
3417
                    {
3418
                        $add = 'selected ';
3419
                    }
3420
                    else
3421
                    {
3422
                        $add = '';
3423
                    }
3424
                    $output.= '<option '.$add.'value="'.$cate_arbo[$key]['id'].'">'.dol_trunc($cate_arbo[$key]['fulllabel'],$maxlength,'middle').'</option>';
3425
3426
					$outarray[$cate_arbo[$key]['id']] = $cate_arbo[$key]['fulllabel'];
3427
                }
3428
            }
3429
        }
3430
        $output.= '</select>';
3431
        $output.= "\n";
3432
3433
		if ($outputmode) return $outarray;
3434
		return $output;
3435
    }
3436
3437
    /**
3438
     *     Show a confirmation HTML form or AJAX popup
3439
     *
3440
     *     @param	string		$page        	   	Url of page to call if confirmation is OK
3441
     *     @param	string		$title       	   	Title
3442
     *     @param	string		$question    	   	Question
3443
     *     @param 	string		$action      	   	Action
3444
     *	   @param	array		$formquestion	   	An array with forms complementary inputs
3445
     * 	   @param	string		$selectedchoice		"" or "no" or "yes"
3446
     * 	   @param	int			$useajax		   	0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=preoutput confirm box with div id=dialog-confirm-xxx
3447
     *     @param	int			$height          	Force height of box
3448
     *     @param	int			$width				Force width of box
3449
     *     @return 	void
3450
     *     @deprecated
3451
     *     @see formconfirm()
3452
     */
3453
    function form_confirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=170, $width=500)
3454
    {
3455
        print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
3456
    }
3457
3458
    /**
3459
     *     Show a confirmation HTML form or AJAX popup.
3460
     *     Easiest way to use this is with useajax=1.
3461
     *     If you use useajax='xxx', you must also add jquery code to trigger opening of box (with correct parameters)
3462
     *     just after calling this method. For example:
3463
     *       print '<script type="text/javascript">'."\n";
3464
     *       print 'jQuery(document).ready(function() {'."\n";
3465
     *       print 'jQuery(".xxxlink").click(function(e) { jQuery("#aparamid").val(jQuery(this).attr("rel")); jQuery("#dialog-confirm-xxx").dialog("open"); return false; });'."\n";
3466
     *       print '});'."\n";
3467
     *       print '</script>'."\n";
3468
     *
3469
     *     @param  	string		$page        	   	Url of page to call if confirmation is OK
3470
     *     @param	string		$title       	   	Title
3471
     *     @param	string		$question    	   	Question
3472
     *     @param 	string		$action      	   	Action
3473
     *	   @param  	array		$formquestion	   	An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , ))
3474
     * 	   @param  	string		$selectedchoice  	"" or "no" or "yes"
3475
     * 	   @param  	int			$useajax		   	0=No, 1=Yes, 2=Yes but submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx
3476
     *     @param  	int			$height          	Force height of box
3477
     *     @param	int			$width				Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones.
3478
     *     @return 	string      	    			HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form
3479
     */
3480
    function formconfirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=200, $width=500)
3481
    {
3482
        global $langs,$conf;
3483
        global $useglobalvars;
3484
3485
        $more='';
3486
        $formconfirm='';
3487
        $inputok=array();
3488
        $inputko=array();
3489
3490
        // Clean parameters
3491
        $newselectedchoice=empty($selectedchoice)?"no":$selectedchoice;
3492
        if ($conf->browser->layout == 'phone') $width='95%';
3493
3494
        if (is_array($formquestion) && ! empty($formquestion))
3495
        {
3496
        	// First add hidden fields and value
3497
        	foreach ($formquestion as $key => $input)
3498
            {
3499
                if (is_array($input) && ! empty($input))
3500
                {
3501
                	if ($input['type'] == 'hidden')
3502
                    {
3503
                        $more.='<input type="hidden" id="'.$input['name'].'" name="'.$input['name'].'" value="'.dol_escape_htmltag($input['value']).'">'."\n";
3504
                    }
3505
                }
3506
            }
3507
3508
        	// Now add questions
3509
            $more.='<table class="paddingtopbottomonly" width="100%">'."\n";
3510
            $more.='<tr><td colspan="3">'.(! empty($formquestion['text'])?$formquestion['text']:'').'</td></tr>'."\n";
3511
            foreach ($formquestion as $key => $input)
3512
            {
3513
                if (is_array($input) && ! empty($input))
3514
                {
3515
                	$size=(! empty($input['size'])?' size="'.$input['size'].'"':'');
3516
3517
                    if ($input['type'] == 'text')
3518
                    {
3519
                        $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="text" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n";
3520
                    }
3521
                    else if ($input['type'] == 'password')
3522
                    {
3523
                        $more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="password" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'" /></td></tr>'."\n";
3524
                    }
3525
                    else if ($input['type'] == 'select')
3526
                    {
3527
                        $more.='<tr><td>';
3528
                        if (! empty($input['label'])) $more.=$input['label'].'</td><td valign="top" colspan="2" align="left">';
3529
                        $more.=$this->selectarray($input['name'],$input['values'],$input['default'],1);
3530
                        $more.='</td></tr>'."\n";
3531
                    }
3532
                    else if ($input['type'] == 'checkbox')
3533
                    {
3534
                        $more.='<tr>';
3535
                        $more.='<td>'.$input['label'].' </td><td align="left">';
3536
                        $more.='<input type="checkbox" class="flat" id="'.$input['name'].'" name="'.$input['name'].'"';
3537
                        if (! is_bool($input['value']) && $input['value'] != 'false') $more.=' checked';
3538
                        if (is_bool($input['value']) && $input['value']) $more.=' checked';
3539
                        if (isset($input['disabled'])) $more.=' disabled';
3540
                        $more.=' /></td>';
3541
                        $more.='<td align="left">&nbsp;</td>';
3542
                        $more.='</tr>'."\n";
3543
                    }
3544
                    else if ($input['type'] == 'radio')
3545
                    {
3546
                        $i=0;
3547
                        foreach($input['values'] as $selkey => $selval)
3548
                        {
3549
                            $more.='<tr>';
3550
                            if ($i==0) $more.='<td class="tdtop">'.$input['label'].'</td>';
3551
                            else $more.='<td>&nbsp;</td>';
3552
                            $more.='<td width="20"><input type="radio" class="flat" id="'.$input['name'].'" name="'.$input['name'].'" value="'.$selkey.'"';
3553
                            if ($input['disabled']) $more.=' disabled';
3554
                            $more.=' /></td>';
3555
                            $more.='<td align="left">';
3556
                            $more.=$selval;
3557
                            $more.='</td></tr>'."\n";
3558
                            $i++;
3559
                        }
3560
                    }
3561
					else if ($input['type'] == 'date')
3562
					{
3563
						$more.='<tr><td>'.$input['label'].'</td>';
3564
						$more.='<td colspan="2" align="left">';
3565
						$more.=$this->select_date($input['value'],$input['name'],0,0,0,'',1,0,1);
3566
						$more.='</td></tr>'."\n";
3567
						$formquestion[] = array('name'=>$input['name'].'day');
3568
						$formquestion[] = array('name'=>$input['name'].'month');
3569
						$formquestion[] = array('name'=>$input['name'].'year');
3570
						$formquestion[] = array('name'=>$input['name'].'hour');
3571
						$formquestion[] = array('name'=>$input['name'].'min');
3572
					}
3573
                    else if ($input['type'] == 'other')
3574
                    {
3575
                        $more.='<tr><td>';
3576
                        if (! empty($input['label'])) $more.=$input['label'].'</td><td colspan="2" align="left">';
3577
                        $more.=$input['value'];
3578
                        $more.='</td></tr>'."\n";
3579
                    }
3580
                }
3581
            }
3582
            $more.='</table>'."\n";
3583
        }
3584
3585
		// JQUI method dialog is broken with jmobile, we use standard HTML.
3586
		// Note: When using dol_use_jmobile or no js, you must also check code for button use a GET url with action=xxx and check that you also output the confirm code when action=xxx
3587
		// See page product/card.php for example
3588
        if (! empty($conf->dol_use_jmobile)) $useajax=0;
3589
		if (empty($conf->use_javascript_ajax)) $useajax=0;
3590
3591
        if ($useajax)
3592
        {
3593
            $autoOpen=true;
3594
            $dialogconfirm='dialog-confirm';
3595
            $button='';
3596
            if (! is_numeric($useajax))
3597
            {
3598
                $button=$useajax;
3599
                $useajax=1;
3600
                $autoOpen=false;
3601
                $dialogconfirm.='-'.$button;
3602
            }
3603
            $pageyes=$page.(preg_match('/\?/',$page)?'&':'?').'action='.$action.'&confirm=yes';
3604
            $pageno=($useajax == 2 ? $page.(preg_match('/\?/',$page)?'&':'?').'confirm=no':'');
3605
            // Add input fields into list of fields to read during submit (inputok and inputko)
3606
            if (is_array($formquestion))
3607
            {
3608
                foreach ($formquestion as $key => $input)
3609
                {
3610
                	//print "xx ".$key." rr ".is_array($input)."<br>\n";
3611
                    if (is_array($input) && isset($input['name'])) array_push($inputok,$input['name']);
3612
                    if (isset($input['inputko']) && $input['inputko'] == 1) array_push($inputko,$input['name']);
3613
                }
3614
            }
3615
			// Show JQuery confirm box. Note that global var $useglobalvars is used inside this template
3616
            $formconfirm.= '<div id="'.$dialogconfirm.'" title="'.dol_escape_htmltag($title).'" style="display: none;">';
3617
            if (! empty($more)) {
3618
            	$formconfirm.= '<div class="confirmquestions">'.$more.'</div>';
3619
            }
3620
            $formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': '');
3621
            $formconfirm.= '</div>'."\n";
3622
3623
            $formconfirm.= "\n<!-- begin ajax form_confirm page=".$page." -->\n";
3624
            $formconfirm.= '<script type="text/javascript">'."\n";
3625
            $formconfirm.= 'jQuery(document).ready(function() {
3626
            $(function() {
3627
            	$( "#'.$dialogconfirm.'" ).dialog(
3628
            	{
3629
                    autoOpen: '.($autoOpen ? "true" : "false").',';
3630
            		if ($newselectedchoice == 'no')
3631
            		{
3632
						$formconfirm.='
3633
						open: function() {
3634
            				$(this).parent().find("button.ui-button:eq(2)").focus();
3635
						},';
3636
            		}
3637
        			$formconfirm.='
3638
                    resizable: false,
3639
                    height: "'.$height.'",
3640
                    width: "'.$width.'",
3641
                    modal: true,
3642
                    closeOnEscape: false,
3643
                    buttons: {
3644
                        "'.dol_escape_js($langs->transnoentities("Yes")).'": function() {
3645
                        	var options="";
3646
                        	var inputok = '.json_encode($inputok).';
3647
                         	var pageyes = "'.dol_escape_js(! empty($pageyes)?$pageyes:'').'";
3648
                         	if (inputok.length>0) {
3649
                         		$.each(inputok, function(i, inputname) {
3650
                         			var more = "";
3651
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3652
                         		    if ($("#" + inputname).attr("type") == "radio") { more = ":checked"; }
3653
                         			var inputvalue = $("#" + inputname + more).val();
3654
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3655
                         			options += "&" + inputname + "=" + inputvalue;
3656
                         		});
3657
                         	}
3658
                         	var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options;
3659
                         	//alert(urljump);
3660
            				if (pageyes.length > 0) { location.href = urljump; }
3661
                            $(this).dialog("close");
3662
                        },
3663
                        "'.dol_escape_js($langs->transnoentities("No")).'": function() {
3664
                        	var options = "";
3665
                         	var inputko = '.json_encode($inputko).';
3666
                         	var pageno="'.dol_escape_js(! empty($pageno)?$pageno:'').'";
3667
                         	if (inputko.length>0) {
3668
                         		$.each(inputko, function(i, inputname) {
3669
                         			var more = "";
3670
                         			if ($("#" + inputname).attr("type") == "checkbox") { more = ":checked"; }
3671
                         			var inputvalue = $("#" + inputname + more).val();
3672
                         			if (typeof inputvalue == "undefined") { inputvalue=""; }
3673
                         			options += "&" + inputname + "=" + inputvalue;
3674
                         		});
3675
                         	}
3676
                         	var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options;
3677
                         	//alert(urljump);
3678
            				if (pageno.length > 0) { location.href = urljump; }
3679
                            $(this).dialog("close");
3680
                        }
3681
                    }
3682
                }
3683
                );
3684
3685
            	var button = "'.$button.'";
3686
            	if (button.length > 0) {
3687
                	$( "#" + button ).click(function() {
3688
                		$("#'.$dialogconfirm.'").dialog("open");
3689
        			});
3690
                }
3691
            });
3692
            });
3693
            </script>';
3694
            $formconfirm.= "<!-- end ajax form_confirm -->\n";
3695
        }
3696
        else
3697
        {
3698
        	$formconfirm.= "\n<!-- begin form_confirm page=".$page." -->\n";
3699
3700
            $formconfirm.= '<form method="POST" action="'.$page.'" class="notoptoleftroright">'."\n";
3701
            $formconfirm.= '<input type="hidden" name="action" value="'.$action.'">'."\n";
3702
            $formconfirm.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n";
3703
3704
            $formconfirm.= '<table width="100%" class="valid">'."\n";
3705
3706
            // Line title
3707
            $formconfirm.= '<tr class="validtitre"><td class="validtitre" colspan="3">'.img_picto('','recent').' '.$title.'</td></tr>'."\n";
3708
3709
            // Line form fields
3710
            if ($more)
3711
            {
3712
                $formconfirm.='<tr class="valid"><td class="valid" colspan="3">'."\n";
3713
                $formconfirm.=$more;
3714
                $formconfirm.='</td></tr>'."\n";
3715
            }
3716
3717
            // Line with question
3718
            $formconfirm.= '<tr class="valid">';
3719
            $formconfirm.= '<td class="valid">'.$question.'</td>';
3720
            $formconfirm.= '<td class="valid">';
3721
            $formconfirm.= $this->selectyesno("confirm",$newselectedchoice);
3722
            $formconfirm.= '</td>';
3723
            $formconfirm.= '<td class="valid" align="center"><input class="button valignmiddle" type="submit" value="'.$langs->trans("Validate").'"></td>';
3724
            $formconfirm.= '</tr>'."\n";
3725
3726
            $formconfirm.= '</table>'."\n";
3727
3728
            $formconfirm.= "</form>\n";
3729
            $formconfirm.= '<br>';
3730
3731
            $formconfirm.= "<!-- end form_confirm -->\n";
3732
        }
3733
3734
        return $formconfirm;
3735
    }
3736
3737
3738
    /**
3739
     *    Show a form to select a project
3740
     *
3741
     *    @param	int		$page        		Page
3742
     *    @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)
3743
     *    @param    int		$selected    		Id pre-selected project
3744
     *    @param    string	$htmlname    		Name of select field
3745
     *    @param	int		$discard_closed		Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable)
3746
     *    @param	int		$maxlength			Max length
3747
     *    @param	int		$forcefocus			Force focus on field (works with javascript only)
3748
     *    @param    int     $nooutput           No print is done. String is returned.
3749
     *    @return	string                      Return html content
3750
     */
3751
    function form_project($page, $socid, $selected='', $htmlname='projectid', $discard_closed=0, $maxlength=20, $forcefocus=0, $nooutput=0)
3752
    {
3753
        global $langs;
3754
3755
        require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
3756
        require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
3757
3758
        $out='';
3759
3760
        $formproject=new FormProjets($this->db);
3761
3762
        $langs->load("project");
3763
        if ($htmlname != "none")
3764
        {
3765
            $out.="\n";
3766
            $out.='<form method="post" action="'.$page.'">';
3767
            $out.='<input type="hidden" name="action" value="classin">';
3768
            $out.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3769
            $out.=$formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1);
3770
            $out.='<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
3771
            $out.='</form>';
3772
        }
3773
        else
3774
        {
3775
            if ($selected)
3776
            {
3777
                $projet = new Project($this->db);
3778
                $projet->fetch($selected);
3779
                //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>';
3780
                $out.=$projet->getNomUrl(0,'',1);
3781
            }
3782
            else
3783
            {
3784
                $out.="&nbsp;";
3785
            }
3786
        }
3787
3788
        if (empty($nooutput))
3789
        {
3790
            print $out;
3791
            return '';
3792
        }
3793
        return $out;
3794
    }
3795
3796
    /**
3797
     *	Show a form to select payment conditions
3798
     *
3799
     *  @param	int		$page        	Page
3800
     *  @param  string	$selected    	Id condition pre-selectionne
3801
     *  @param  string	$htmlname    	Name of select html field
3802
     *	@param	int		$addempty		Add empty entry
3803
     *  @return	void
3804
     */
3805
    function form_conditions_reglement($page, $selected='', $htmlname='cond_reglement_id', $addempty=0)
3806
    {
3807
        global $langs;
3808
        if ($htmlname != "none")
3809
        {
3810
            print '<form method="post" action="'.$page.'">';
3811
            print '<input type="hidden" name="action" value="setconditions">';
3812
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3813
            $this->select_conditions_paiements($selected,$htmlname,-1,$addempty);
3814
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3815
            print '</form>';
3816
        }
3817
        else
3818
        {
3819
            if ($selected)
3820
            {
3821
                $this->load_cache_conditions_paiements();
3822
                print $this->cache_conditions_paiements[$selected]['label'];
3823
            } else {
3824
                print "&nbsp;";
3825
            }
3826
        }
3827
    }
3828
3829
    /**
3830
     *  Show a form to select a delivery delay
3831
     *
3832
     *  @param  int		$page        	Page
3833
     *  @param  string	$selected    	Id condition pre-selectionne
3834
     *  @param  string	$htmlname    	Name of select html field
3835
     *	@param	int		$addempty		Ajoute entree vide
3836
     *  @return	void
3837
     */
3838
    function form_availability($page, $selected='', $htmlname='availability', $addempty=0)
3839
    {
3840
        global $langs;
3841
        if ($htmlname != "none")
3842
        {
3843
            print '<form method="post" action="'.$page.'">';
3844
            print '<input type="hidden" name="action" value="setavailability">';
3845
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3846
            $this->selectAvailabilityDelay($selected,$htmlname,-1,$addempty);
3847
            print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
3848
            print '</form>';
3849
        }
3850
        else
3851
        {
3852
            if ($selected)
3853
            {
3854
                $this->load_cache_availability();
3855
                print $this->cache_availability[$selected]['label'];
3856
            } else {
3857
                print "&nbsp;";
3858
            }
3859
        }
3860
    }
3861
3862
    /**
3863
	 *	Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...)
3864
	 *  List found into table c_input_reason loaded by loadCacheInputReason
3865
     *
3866
     *  @param  string	$page        	Page
3867
     *  @param  string	$selected    	Id condition pre-selectionne
3868
     *  @param  string	$htmlname    	Name of select html field
3869
     *	@param	int		$addempty		Add empty entry
3870
     *  @return	void
3871
     */
3872
    function formInputReason($page, $selected='', $htmlname='demandreason', $addempty=0)
3873
    {
3874
        global $langs;
3875
        if ($htmlname != "none")
3876
        {
3877
            print '<form method="post" action="'.$page.'">';
3878
            print '<input type="hidden" name="action" value="setdemandreason">';
3879
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3880
            $this->selectInputReason($selected,$htmlname,-1,$addempty);
3881
            print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
3882
            print '</form>';
3883
        }
3884
        else
3885
        {
3886
            if ($selected)
3887
            {
3888
                $this->loadCacheInputReason();
3889
                foreach ($this->cache_demand_reason as $key => $val)
3890
                {
3891
                    if ($val['id'] == $selected)
3892
                    {
3893
                        print $val['label'];
3894
                        break;
3895
                    }
3896
                }
3897
            } else {
3898
                print "&nbsp;";
3899
            }
3900
        }
3901
    }
3902
3903
    /**
3904
     *    Show a form + html select a date
3905
     *
3906
     *    @param	string		$page        	Page
3907
     *    @param	string		$selected    	Date preselected
3908
     *    @param    string		$htmlname    	Html name of date input fields or 'none'
3909
     *    @param    int			$displayhour 	Display hour selector
3910
     *    @param    int			$displaymin		Display minutes selector
3911
     *    @param	int			$nooutput		1=No print output, return string
3912
     *    @return	string
3913
     *    @see		select_date
3914
     */
3915
    function form_date($page, $selected, $htmlname, $displayhour=0, $displaymin=0, $nooutput=0)
3916
    {
3917
        global $langs;
3918
3919
        $ret='';
3920
3921
        if ($htmlname != "none")
3922
        {
3923
            $ret.='<form method="post" action="'.$page.'" name="form'.$htmlname.'">';
3924
            $ret.='<input type="hidden" name="action" value="set'.$htmlname.'">';
3925
            $ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3926
            $ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
3927
            $ret.='<tr><td>';
3928
            $ret.=$this->select_date($selected,$htmlname,$displayhour,$displaymin,1,'form'.$htmlname,1,0,1);
3929
            $ret.='</td>';
3930
            $ret.='<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
3931
            $ret.='</tr></table></form>';
3932
        }
3933
        else
3934
        {
3935
        	if ($displayhour) $ret.=dol_print_date($selected,'dayhour');
3936
        	else $ret.=dol_print_date($selected,'day');
3937
        }
3938
3939
        if (empty($nooutput)) print $ret;
3940
        return $ret;
3941
    }
3942
3943
3944
    /**
3945
     *  Show a select form to choose a user
3946
     *
3947
     *  @param	string	$page        	Page
3948
     *  @param  string	$selected    	Id of user preselected
3949
     *  @param  string	$htmlname    	Name of input html field. If 'none', we just output the user link.
3950
     *  @param  array	$exclude		List of users id to exclude
3951
     *  @param  array	$include        List of users id to include
3952
     *  @return	void
3953
     */
3954
    function form_users($page, $selected='', $htmlname='userid', $exclude='', $include='')
3955
    {
3956
        global $langs;
3957
3958
        if ($htmlname != "none")
3959
        {
3960
            print '<form method="POST" action="'.$page.'" name="form'.$htmlname.'">';
3961
            print '<input type="hidden" name="action" value="set'.$htmlname.'">';
3962
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3963
            print $this->select_dolusers($selected,$htmlname,1,$exclude,0,$include);
3964
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3965
            print '</form>';
3966
        }
3967
        else
3968
		{
3969
            if ($selected)
3970
            {
3971
                require_once DOL_DOCUMENT_ROOT .'/user/class/user.class.php';
3972
                $theuser=new User($this->db);
3973
                $theuser->fetch($selected);
3974
                print $theuser->getNomUrl(1);
3975
            } else {
3976
                print "&nbsp;";
3977
            }
3978
        }
3979
    }
3980
3981
3982
    /**
3983
     *    Show form with payment mode
3984
     *
3985
     *    @param	string	$page        	Page
3986
     *    @param    int		$selected    	Id mode pre-selectionne
3987
     *    @param    string	$htmlname    	Name of select html field
3988
     *    @param  	string	$filtertype		To filter on field type in llx_c_paiement (array('code'=>xx,'label'=>zz))
3989
     *    @param    int     $active         Active or not, -1 = all
3990
     *    @return	void
3991
     */
3992
    function form_modes_reglement($page, $selected='', $htmlname='mode_reglement_id', $filtertype='', $active=1)
3993
    {
3994
        global $langs;
3995
        if ($htmlname != "none")
3996
        {
3997
            print '<form method="POST" action="'.$page.'">';
3998
            print '<input type="hidden" name="action" value="setmode">';
3999
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4000
            $this->select_types_paiements($selected,$htmlname,$filtertype,0,0,0,0,$active);
4001
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4002
            print '</form>';
4003
        }
4004
        else
4005
        {
4006
            if ($selected)
4007
            {
4008
                $this->load_cache_types_paiements();
4009
                print $this->cache_types_paiements[$selected]['label'];
4010
            } else {
4011
                print "&nbsp;";
4012
            }
4013
        }
4014
    }
4015
4016
	/**
4017
     *    Show form with multicurrency code
4018
     *
4019
     *    @param	string	$page        	Page
4020
     *    @param    string	$selected    	code pre-selectionne
4021
     *    @param    string	$htmlname    	Name of select html field
4022
     *    @return	void
4023
     */
4024
    function form_multicurrency_code($page, $selected='', $htmlname='multicurrency_code')
4025
    {
4026
        global $langs;
4027
        if ($htmlname != "none")
4028
        {
4029
            print '<form method="POST" action="'.$page.'">';
4030
            print '<input type="hidden" name="action" value="setmulticurrencycode">';
4031
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4032
            print $this->selectMultiCurrency($selected, $htmlname, 0);
4033
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4034
            print '</form>';
4035
        }
4036
        else
4037
        {
4038
        	dol_include_once('/core/lib/company.lib.php');
4039
        	print !empty($selected) ? currency_name($selected,1) : '&nbsp;';
4040
        }
4041
    }
4042
4043
	/**
4044
     *    Show form with multicurrency rate
4045
     *
4046
     *    @param	string	$page        	Page
4047
     *    @param    double	$rate	    	Current rate
4048
     *    @param    string	$htmlname    	Name of select html field
4049
     *    @param    string  $currency       Currency code to explain the rate
4050
     *    @return	void
4051
     */
4052
    function form_multicurrency_rate($page, $rate='', $htmlname='multicurrency_tx', $currency='')
4053
    {
4054
        global $langs, $mysoc, $conf;
4055
4056
        if ($htmlname != "none")
4057
        {
4058
            print '<form method="POST" action="'.$page.'">';
4059
            print '<input type="hidden" name="action" value="setmulticurrencyrate">';
4060
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4061
            print '<input type="text" name="'.$htmlname.'" value="'.(!empty($rate) ? price($rate) : 1).'" size="10" /> ';
4062
			print '<select name="calculation_mode">';
4063
			print '<option value="1">'.$currency.' > '.$conf->currency.'</option>';
4064
			print '<option value="2">'.$conf->currency.' > '.$currency.'</option>';
4065
			print '</select> ';
4066
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4067
            print '</form>';
4068
        }
4069
        else
4070
        {
4071
        	if (! empty($rate))
4072
        	{
4073
        	    print price($rate, 1, $langs, 1, 0);
4074
        	    if ($currency && $rate != 1) print ' &nbsp; ('.price($rate, 1, $langs, 1, 0).' '.$currency.' = 1 '.$conf->currency.')';
4075
        	}
4076
        	else
4077
        	{
4078
        	    print 1;
4079
        	}
4080
        }
4081
    }
4082
4083
4084
    /**
4085
     *	Show a select box with available absolute discounts
4086
     *
4087
     *  @param  string	$page        	Page URL where form is shown
4088
     *  @param  int		$selected    	Value pre-selected
4089
     *	@param  string	$htmlname    	Name of SELECT component. If 'none', not changeable. Example 'remise_id'.
4090
     *	@param	int		$socid			Third party id
4091
     * 	@param	float	$amount			Total amount available
4092
     * 	@param	string	$filter			SQL filter on discounts
4093
     * 	@param	int		$maxvalue		Max value for lines that can be selected
4094
     *  @param  string	$more           More string to add
4095
     *  @param  int     $hidelist       1=Hide list
4096
     *  @return	void
4097
     */
4098
    function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0)
4099
    {
4100
        global $conf,$langs;
4101
        if ($htmlname != "none")
4102
        {
4103
            print '<form method="post" action="'.$page.'">';
4104
            print '<input type="hidden" name="action" value="setabsolutediscount">';
4105
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4106
            print '<div class="inline-block">';
4107
            if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
4108
            {
4109
                if (! $filter || $filter=="fk_facture_source IS NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));    // If we want deposit to be substracted to payments only and not to total of final invoice
4110
                else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
4111
            }
4112
            else
4113
            {
4114
                if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));
4115
                else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
4116
            }
4117
            if (empty($hidelist)) print ': ';
4118
            print '</div>';
4119
            if (empty($hidelist))
4120
            {
4121
                print '<div class="inline-block" style="padding-right: 10px">';
4122
                $newfilter='fk_facture IS NULL AND fk_facture_line IS NULL';	// Remises disponibles
4123
                if ($filter) $newfilter.=' AND ('.$filter.')';
4124
                $nbqualifiedlines=$this->select_remises($selected,$htmlname,$newfilter,$socid,$maxvalue);
4125
                if ($nbqualifiedlines > 0)
4126
                {
4127
                    print ' &nbsp; <input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("UseLine")).'"';
4128
                    if ($filter && $filter != "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')") print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"';
4129
                    print '>';
4130
                }
4131
                print '</div>';
4132
            }
4133
            if ($more) 
4134
            {
4135
                print '<div class="inline-block">';
4136
                print $more;
4137
                print '</div>';
4138
            }
4139
            print '</form>';
4140
        }
4141
        else
4142
        {
4143
            if ($selected)
4144
            {
4145
                print $selected;
4146
            }
4147
            else
4148
            {
4149
                print "0";
4150
            }
4151
        }
4152
    }
4153
4154
4155
    /**
4156
     *    Show forms to select a contact
4157
     *
4158
     *    @param	string		$page        	Page
4159
     *    @param	Societe		$societe		Filter on third party
4160
     *    @param    int			$selected    	Id contact pre-selectionne
4161
     *    @param    string		$htmlname    	Name of HTML select. If 'none', we just show contact link.
4162
     *    @return	void
4163
     */
4164
    function form_contacts($page, $societe, $selected='', $htmlname='contactid')
4165
    {
4166
        global $langs, $conf;
4167
4168
        if ($htmlname != "none")
4169
        {
4170
            print '<form method="post" action="'.$page.'">';
4171
            print '<input type="hidden" name="action" value="set_contact">';
4172
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4173
            print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
4174
            print '<tr><td>';
4175
            $num=$this->select_contacts($societe->id, $selected, $htmlname);
4176
            if ($num==0)
4177
            {
4178
            	$addcontact = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress"));
4179
                print '<a href="'.DOL_URL_ROOT.'/contact/card.php?socid='.$societe->id.'&amp;action=create&amp;backtoreferer=1">'.$addcontact.'</a>';
4180
            }
4181
            print '</td>';
4182
            print '<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
4183
            print '</tr></table></form>';
4184
        }
4185
        else
4186
        {
4187
            if ($selected)
4188
            {
4189
                require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php';
4190
                $contact=new Contact($this->db);
4191
                $contact->fetch($selected);
4192
                print $contact->getFullName($langs);
4193
            } else {
4194
                print "&nbsp;";
4195
            }
4196
        }
4197
    }
4198
4199
    /**
4200
     *  Output html select to select thirdparty
4201
     *
4202
     *  @param	string	$page       	Page
4203
     *  @param  string	$selected   	Id preselected
4204
     *  @param  string	$htmlname		Name of HTML select
4205
     *  @param  string	$filter         optional filters criteras
4206
     *	@param	int		$showempty		Add an empty field
4207
     * 	@param	int		$showtype		Show third party type in combolist (customer, prospect or supplier)
4208
     * 	@param	int		$forcecombo		Force to use combo box
4209
     *  @param	array	$events			Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
4210
     *  @return	void
4211
     */
4212
    function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array())
4213
    {
4214
        global $langs;
4215
4216
        if ($htmlname != "none")
4217
        {
4218
            print '<form method="post" action="'.$page.'">';
4219
            print '<input type="hidden" name="action" value="set_thirdparty">';
4220
            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
4221
            print $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events);
4222
            print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
4223
            print '</form>';
4224
        }
4225
        else
4226
        {
4227
            if ($selected)
4228
            {
4229
                require_once DOL_DOCUMENT_ROOT .'/societe/class/societe.class.php';
4230
                $soc = new Societe($this->db);
4231
                $soc->fetch($selected);
4232
                print $soc->getNomUrl($langs);
4233
            }
4234
            else
4235
            {
4236
                print "&nbsp;";
4237
            }
4238
        }
4239
    }
4240
4241
    /**
4242
     *    Retourne la liste des devises, dans la langue de l'utilisateur
4243
     *
4244
     *    @param	string	$selected    preselected currency code
4245
     *    @param    string	$htmlname    name of HTML select list
4246
     *    @return	void
4247
     */
4248
    function select_currency($selected='',$htmlname='currency_id')
4249
    {
4250
        print $this->selectcurrency($selected,$htmlname);
4251
    }
4252
4253
    /**
4254
     *  Retourne la liste des devises, dans la langue de l'utilisateur
4255
     *
4256
     *  @param	string	$selected    preselected currency code
4257
     *  @param  string	$htmlname    name of HTML select list
4258
     * 	@return	string
4259
     */
4260
    function selectCurrency($selected='',$htmlname='currency_id')
4261
    {
4262
        global $conf,$langs,$user;
4263
4264
        $langs->loadCacheCurrencies('');
4265
4266
        $out='';
4267
4268
        if ($selected=='euro' || $selected=='euros') $selected='EUR';   // Pour compatibilite
4269
4270
        $out.= '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';
4271
        foreach ($langs->cache_currencies as $code_iso => $currency)
4272
        {
4273
        	if ($selected && $selected == $code_iso)
4274
        	{
4275
        		$out.= '<option value="'.$code_iso.'" selected>';
4276
        	}
4277
        	else
4278
        	{
4279
        		$out.= '<option value="'.$code_iso.'">';
4280
        	}
4281
        	$out.= $currency['label'];
4282
        	$out.= ' ('.$langs->getCurrencySymbol($code_iso).')';
4283
        	$out.= '</option>';
4284
        }
4285
        $out.= '</select>';
4286
        if ($user->admin) $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
4287
        return $out;
4288
    }
4289
4290
	/**
4291
     *	Return array of currencies in user language
4292
	 *
4293
     *  @param	string	$selected    preselected currency code
4294
     *  @param  string	$htmlname    name of HTML select list
4295
     *  @param  integer	$useempty    1=Add empty line
4296
     * 	@return	string
4297
     */
4298
    function selectMultiCurrency($selected='', $htmlname='multicurrency_code', $useempty=0)
4299
    {
4300
        global $db,$conf,$langs,$user;
4301
4302
        $langs->loadCacheCurrencies('');        // Load ->cache_currencies
4303
4304
		$TCurrency = array();
4305
4306
		$sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'multicurrency';
4307
		$sql.= " WHERE entity IN ('".getEntity('mutlicurrency')."')";
4308
		$resql = $db->query($sql);
4309
		if ($resql)
4310
		{
4311
			while ($obj = $db->fetch_object($resql)) $TCurrency[$obj->code] = $obj->code;
4312
		}
4313
4314
		$out='';
4315
        $out.= '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';
4316
		if ($useempty) $out .= '<option value=""></option>';
4317
		// If company current currency not in table, we add it into list. Should always be available.
4318
		if (! in_array($conf->currency, $TCurrency))
4319
		{
4320
		    $TCurrency[$conf->currency] = $conf->currency;
4321
		}
4322
		if (count($TCurrency) > 0)
4323
		{
4324
			foreach ($langs->cache_currencies as $code_iso => $currency)
4325
	        {
4326
	        	if (isset($TCurrency[$code_iso]))
4327
				{
4328
					if (!empty($selected) && $selected == $code_iso) $out.= '<option value="'.$code_iso.'" selected="selected">';
4329
		        	else $out.= '<option value="'.$code_iso.'">';
4330
4331
		        	$out.= $currency['label'];
4332
		        	$out.= ' ('.$langs->getCurrencySymbol($code_iso).')';
4333
		        	$out.= '</option>';
4334
				}
4335
	        }
4336
4337
		}
4338
4339
        $out.= '</select>';
4340
		// Make select dynamic
4341
		include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4342
		$out.= ajax_combobox($htmlname);
4343
4344
        return $out;
4345
    }
4346
4347
    /**
4348
     *	Load into the cache vat rates of a country
4349
     *
4350
     *	@param	string	$country_code		Country code with quotes ("'CA'", or "'CA,IN,...'")
4351
     *	@return	int							Nb of loaded lines, 0 if already loaded, <0 if KO
4352
     */
4353
    function load_cache_vatrates($country_code)
4354
    {
4355
    	global $langs;
4356
4357
    	$num = count($this->cache_vatrates);
4358
    	if ($num > 0) return $num;    // Cache already loaded
4359
4360
        dol_syslog(__METHOD__, LOG_DEBUG);
4361
4362
        $sql  = "SELECT DISTINCT t.rowid, t.code, t.taux, t.recuperableonly";
4363
    	$sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
4364
    	$sql.= " WHERE t.fk_pays = c.rowid";
4365
    	$sql.= " AND t.active > 0";
4366
    	$sql.= " AND c.code IN (".$country_code.")";
4367
    	$sql.= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC";
4368
4369
    	$resql=$this->db->query($sql);
4370
    	if ($resql)
4371
    	{
4372
    		$num = $this->db->num_rows($resql);
4373
    		if ($num)
4374
    		{
4375
    			for ($i = 0; $i < $num; $i++)
4376
    			{
4377
    				$obj = $this->db->fetch_object($resql);
4378
    				$this->cache_vatrates[$i]['rowid']	= $obj->rowid;
4379
    				$this->cache_vatrates[$i]['code']	= $obj->code;
4380
    				$this->cache_vatrates[$i]['txtva']	= $obj->taux;
4381
    				$this->cache_vatrates[$i]['libtva']	= $obj->taux.'%'.($obj->code?' ('.$obj->code.')':'');   // Label must contains only 0-9 , . % or *
4382
    				$this->cache_vatrates[$i]['nprtva']	= $obj->recuperableonly;
4383
    			}
4384
4385
    			return $num;
4386
    		}
4387
    		else
4388
    		{
4389
    			$this->error = '<font class="error">'.$langs->trans("ErrorNoVATRateDefinedForSellerCountry",$country_code).'</font>';
4390
    			return -1;
4391
    		}
4392
    	}
4393
    	else
4394
    	{
4395
    		$this->error = '<font class="error">'.$this->db->error().'</font>';
4396
    		return -2;
4397
    	}
4398
    }
4399
4400
    /**
4401
     *  Output an HTML select vat rate.
4402
     *  The name of this function should be selectVat. We keep bad name for compatibility purpose.
4403
     *
4404
     *  @param	string	      $htmlname           Name of HTML select field
4405
     *  @param  float|string  $selectedrate       Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing.
4406
     *  @param  Societe	      $societe_vendeuse   Thirdparty seller
4407
     *  @param  Societe	      $societe_acheteuse  Thirdparty buyer
4408
     *  @param  int		      $idprod             Id product. O if unknown of NA.
4409
     *  @param  int		      $info_bits          Miscellaneous information on line (1 for NPR)
4410
     *  @param  int|string    $type               ''=Unknown, 0=Product, 1=Service (Used if idprod not defined)
4411
     *                  		                  Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle.
4412
     *                  					      Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle.
4413
     *                  					      Si (vendeur et acheteur dans Communaute europeenne) et bien vendu = moyen de transports neuf (auto, bateau, avion), TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle.
4414
	 *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle.
4415
	 *                                            Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle.
4416
     *                  					      Sinon la TVA proposee par defaut=0. Fin de regle.
4417
     *  @param	bool	     $options_only		  Return HTML options lines only (for ajax treatment)
4418
     *  @param  int          $mode                1=Add code into key in select list
4419
     *  @return	string
4420
     */
4421
    function load_tva($htmlname='tauxtva', $selectedrate='', $societe_vendeuse='', $societe_acheteuse='', $idprod=0, $info_bits=0, $type='', $options_only=false, $mode=0)
4422
    {
4423
        global $langs,$conf,$mysoc;
4424
4425
        $return='';
4426
4427
        // Define defaultnpr, defaultttx and defaultcode
4428
        $defaultnpr=($info_bits & 0x01);
4429
        $defaultnpr=(preg_match('/\*/',$selectedrate) ? 1 : $defaultnpr);
4430
        $defaulttx=str_replace('*','',$selectedrate);
4431
        $defaultcode='';
4432
        if (preg_match('/\((.*)\)/', $defaulttx, $reg))
4433
        {
4434
            $defaultcode=$reg[1];
4435
            $defaulttx=preg_replace('/\s*\(.*\)/','',$defaulttx);
4436
        }
4437
        //var_dump($selectedrate.'-'.$defaulttx.'-'.$defaultnpr.'-'.$defaultcode);
4438
4439
        // Check parameters
4440
        if (is_object($societe_vendeuse) && ! $societe_vendeuse->country_code)
4441
        {
4442
            if ($societe_vendeuse->id == $mysoc->id)
4443
            {
4444
                $return.= '<font class="error">'.$langs->trans("ErrorYourCountryIsNotDefined").'</div>';
4445
            }
4446
            else
4447
            {
4448
                $return.= '<font class="error">'.$langs->trans("ErrorSupplierCountryIsNotDefined").'</div>';
4449
            }
4450
            return $return;
4451
        }
4452
4453
        //var_dump($societe_acheteuse);
4454
        //print "name=$name, selectedrate=$selectedrate, seller=".$societe_vendeuse->country_code." buyer=".$societe_acheteuse->country_code." buyer is company=".$societe_acheteuse->isACompany()." idprod=$idprod, info_bits=$info_bits type=$type";
4455
        //exit;
4456
4457
        // Define list of countries to use to search VAT rates to show
4458
        // First we defined code_country to use to find list
4459
        if (is_object($societe_vendeuse))
4460
        {
4461
            $code_country="'".$societe_vendeuse->country_code."'";
4462
        }
4463
        else
4464
        {
4465
            $code_country="'".$mysoc->country_code."'";   // Pour compatibilite ascendente
4466
        }
4467
        if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC))    // If option to have vat for end customer for services is on
4468
        {
4469
            if (! $societe_vendeuse->isInEEC() && (! is_object($societe_acheteuse) || ($societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany())))
0 ignored issues
show
Bug introduced by
It seems like $societe_vendeuse is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
4470
            {
4471
                // We also add the buyer
4472
                if (is_numeric($type))
4473
                {
4474
                    if ($type == 1) // We know product is a service
4475
                    {
4476
                        $code_country.=",'".$societe_acheteuse->country_code."'";
4477
                    }
4478
                }
4479
                else if (! $idprod)  // We don't know type of product
4480
                {
4481
                    $code_country.=",'".$societe_acheteuse->country_code."'";
4482
                }
4483
                else
4484
                {
4485
                    $prodstatic=new Product($this->db);
4486
                    $prodstatic->fetch($idprod);
4487
                    if ($prodstatic->type == Product::TYPE_SERVICE)   // We know product is a service
4488
                    {
4489
                        $code_country.=",'".$societe_acheteuse->country_code."'";
4490
                    }
4491
                }
4492
            }
4493
        }
4494
4495
        // Now we get list
4496
        $num = $this->load_cache_vatrates($code_country);   // If no vat defined, return -1 with message into this->error
4497
4498
        if ($num > 0)
4499
        {
4500
        	// Definition du taux a pre-selectionner (si defaulttx non force et donc vaut -1 ou '')
4501
        	if ($defaulttx < 0 || dol_strlen($defaulttx) == 0)
4502
        	{
4503
        	    $tmpthirdparty=new Societe($this->db);
4504
        		$defaulttx=get_default_tva($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod);
0 ignored issues
show
Bug introduced by
It seems like $societe_vendeuse defined by parameter $societe_vendeuse on line 4421 can also be of type string; however, get_default_tva() does only seem to accept object<Societe>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
4505
        		$defaultnpr=get_default_npr($societe_vendeuse, (is_object($societe_acheteuse)?$societe_acheteuse:$tmpthirdparty), $idprod);
0 ignored issues
show
Bug introduced by
It seems like $societe_vendeuse defined by parameter $societe_vendeuse on line 4421 can also be of type string; however, get_default_npr() does only seem to accept object<Societe>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
4506
        		if (empty($defaulttx)) $defaultnpr=0;
4507
        	}
4508
4509
        	// Si taux par defaut n'a pu etre determine, on prend dernier de la liste.
4510
        	// Comme ils sont tries par ordre croissant, dernier = plus eleve = taux courant
4511
        	if ($defaulttx < 0 || dol_strlen($defaulttx) == 0)
4512
        	{
4513
        		if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) $defaulttx = $this->cache_vatrates[$num-1]['txtva'];
4514
        		else $defaulttx=($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS == 'none' ? '' : $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS);
4515
        	}
4516
4517
        	// Disabled if seller is not subject to VAT
4518
        	$disabled=false; $title='';
4519
        	if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0")
4520
        	{
4521
        		$title=' title="'.$langs->trans('VATIsNotUsed').'"';
4522
        		$disabled=true;
4523
        	}
4524
4525
        	if (! $options_only) $return.= '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').$title.'>';
4526
4527
        	$selectedfound=false;
4528
        	foreach ($this->cache_vatrates as $rate)
4529
        	{
4530
        		// Keep only 0 if seller is not subject to VAT
4531
        		if ($disabled && $rate['txtva'] != 0) continue;
4532
4533
        		// Define key to use into select list
4534
        		$key = $rate['txtva'];
4535
        		$key.= $rate['nprtva'] ? '*': '';
4536
        		if ($mode > 0 && $rate['code']) $key.=' ('.$rate['code'].')';
4537
        		if ($mode < 0) $key = $rate['rowid'];
4538
4539
        		$return.= '<option value="'.$key.'"';
4540
        		if (! $selectedfound)
4541
        		{
4542
            		if ($defaultcode) // If defaultcode is defined, we used it in priority to select combo option instead of using rate+npr flag
4543
            		{
4544
                        if ($defaultcode == $rate['code'])
4545
                        {
4546
                            $return.= ' selected';
4547
                            $selectedfound=true;
4548
                        }
4549
            		}
4550
            		elseif ($rate['txtva'] == $defaulttx && $rate['nprtva'] == $defaultnpr)
4551
               		{
4552
               		    $return.= ' selected';
4553
               		    $selectedfound=true;
4554
            		}
4555
        		}
4556
        		$return.= '>'.vatrate($rate['libtva']);
4557
        		//$return.=($rate['code']?' '.$rate['code']:'');
4558
        		$return.= (empty($rate['code']) && $rate['nprtva']) ? ' *': '';         // We show the *  (old behaviour only if new vat code is not used)
4559
4560
        		$return.= '</option>';
4561
        	}
4562
4563
        	if (! $options_only) $return.= '</select>';
4564
        }
4565
        else
4566
        {
4567
            $return.= $this->error;
4568
        }
4569
4570
        $this->num = $num;
4571
        return $return;
4572
    }
4573
4574
4575
    /**
4576
     *	Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
4577
     *  Fields are preselected with :
4578
     *            	- set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
4579
     *            	- local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
4580
     *            	- Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
4581
     *
4582
     *	@param	timestamp	$set_time 		Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date (emptydate must be 0).
4583
     *	@param	string		$prefix			Prefix for fields name
4584
     *	@param	int			$h				1=Show also hours
4585
     *	@param	int			$m				1=Show also minutes
4586
     *	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
4587
     *	@param	string		$form_name 		Not used
4588
     *	@param	int			$d				1=Show days, month, years
4589
     * 	@param	int			$addnowlink		Add a link "Now"
4590
     * 	@param	int			$nooutput		Do not output html string but return it
4591
     * 	@param 	int			$disabled		Disable input fields
4592
     *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
4593
     *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another select_date field.
4594
     *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
4595
     * 	@return	string|null						Nothing or string if nooutput is 1
4596
     *  @see	form_date
4597
     */
4598
    function select_date($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $nooutput=0, $disabled=0, $fullday='', $addplusone='', $adddateof='')
4599
    {
4600
        global $conf,$langs;
4601
4602
        $retstring='';
4603
4604
        if($prefix=='') $prefix='re';
4605
        if($h == '') $h=0;
4606
        if($m == '') $m=0;
4607
        $emptydate=0;
4608
        $emptyhours=0;
4609
    	if ($empty == 1) { $emptydate=1; $emptyhours=1; }
4610
    	if ($empty == 2) { $emptydate=0; $emptyhours=1; }
4611
		$orig_set_time=$set_time;
4612
4613
        if ($set_time === '' && $emptydate == 0)
4614
        {
4615
        	include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
4616
        	$set_time = dol_now('tzuser')-(getServerTimeZoneInt('now')*3600); // set_time must be relative to PHP server timezone
4617
        }
4618
4619
        // Analysis of the pre-selection date
4620
        if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/',$set_time,$reg))
4621
        {
4622
            // Date format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'
4623
            $syear	= (! empty($reg[1])?$reg[1]:'');
4624
            $smonth	= (! empty($reg[2])?$reg[2]:'');
4625
            $sday	= (! empty($reg[3])?$reg[3]:'');
4626
            $shour	= (! empty($reg[4])?$reg[4]:'');
4627
            $smin	= (! empty($reg[5])?$reg[5]:'');
4628
        }
4629
        elseif (strval($set_time) != '' && $set_time != -1)
4630
        {
4631
            // set_time est un timestamps (0 possible)
4632
            $syear = dol_print_date($set_time, "%Y");
4633
            $smonth = dol_print_date($set_time, "%m");
4634
            $sday = dol_print_date($set_time, "%d");
4635
            if ($orig_set_time != '')
4636
            {
4637
            	$shour = dol_print_date($set_time, "%H");
4638
            	$smin = dol_print_date($set_time, "%M");
4639
            }
4640
        }
4641
        else
4642
        {
4643
            // Date est '' ou vaut -1
4644
            $syear = '';
4645
            $smonth = '';
4646
            $sday = '';
4647
            $shour = !isset($conf->global->MAIN_DEFAULT_DATE_HOUR) ? '' : $conf->global->MAIN_DEFAULT_DATE_HOUR;
4648
            $smin = !isset($conf->global->MAIN_DEFAULT_DATE_MIN) ? '' : $conf->global->MAIN_DEFAULT_DATE_MIN;
4649
        }
4650
4651
        $usecalendar='combo';
4652
        if (! empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) $usecalendar=empty($conf->global->MAIN_POPUP_CALENDAR)?'eldy':$conf->global->MAIN_POPUP_CALENDAR;
4653
		if ($conf->browser->phone) $usecalendar='combo';
4654
4655
        if ($d)
4656
        {
4657
            // Show date with popup
4658
            if ($usecalendar != 'combo')
4659
            {
4660
            	$formated_date='';
4661
                //print "e".$set_time." t ".$conf->format_date_short;
4662
                if (strval($set_time) != '' && $set_time != -1)
4663
                {
4664
                    //$formated_date=dol_print_date($set_time,$conf->format_date_short);
4665
                    $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput"));  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
4666
                }
4667
4668
                // Calendrier popup version eldy
4669
                if ($usecalendar == "eldy")
4670
                {
4671
                    // Zone de saisie manuelle de la date
4672
                    $retstring.='<input id="'.$prefix.'" name="'.$prefix.'" type="text" class="maxwidth75" maxlength="11" value="'.$formated_date.'"';
4673
                    $retstring.=($disabled?' disabled':'');
4674
                    $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "';  // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript
4675
                    $retstring.='>';
4676
4677
                    // Icone calendrier
4678
                    if (! $disabled)
4679
                    {
4680
                        $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons"';
4681
                        $base=DOL_URL_ROOT.'/core/';
4682
                        $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');">'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').'</button>';
4683
                    }
4684
                    else $retstring.='<button id="'.$prefix.'Button" type="button" class="dpInvisibleButtons">'.img_object($langs->trans("Disabled"),'calendarday','class="datecallink"').'</button>';
4685
4686
                    $retstring.='<input type="hidden" id="'.$prefix.'day"   name="'.$prefix.'day"   value="'.$sday.'">'."\n";
4687
                    $retstring.='<input type="hidden" id="'.$prefix.'month" name="'.$prefix.'month" value="'.$smonth.'">'."\n";
4688
                    $retstring.='<input type="hidden" id="'.$prefix.'year"  name="'.$prefix.'year"  value="'.$syear.'">'."\n";
4689
                }
4690
                else
4691
                {
4692
                    print "Bad value of MAIN_POPUP_CALENDAR";
4693
                }
4694
            }
4695
            // Show date with combo selects
4696
            else
4697
			{
4698
			    //$retstring.='<div class="inline-block">';
4699
                // Day
4700
                $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50imp" id="'.$prefix.'day" name="'.$prefix.'day">';
4701
4702
                if ($emptydate || $set_time == -1)
4703
                {
4704
                    $retstring.='<option value="0" selected>&nbsp;</option>';
4705
                }
4706
4707
                for ($day = 1 ; $day <= 31; $day++)
4708
                {
4709
                    $retstring.='<option value="'.$day.'"'.($day == $sday ? ' selected':'').'>'.$day.'</option>';
4710
                }
4711
4712
                $retstring.="</select>";
4713
4714
                $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50onsmartphone" id="'.$prefix.'month" name="'.$prefix.'month">';
4715
                if ($emptydate || $set_time == -1)
4716
                {
4717
                    $retstring.='<option value="0" selected>&nbsp;</option>';
4718
                }
4719
4720
                // Month
4721
                for ($month = 1 ; $month <= 12 ; $month++)
4722
                {
4723
                    $retstring.='<option value="'.$month.'"'.($month == $smonth?' selected':'').'>';
4724
                    $retstring.=dol_print_date(mktime(12,0,0,$month,1,2000),"%b");
4725
                    $retstring.="</option>";
4726
                }
4727
                $retstring.="</select>";
4728
4729
                // Year
4730
                if ($emptydate || $set_time == -1)
4731
                {
4732
                    $retstring.='<input'.($disabled?' disabled':'').' placeholder="'.dol_escape_htmltag($langs->trans("Year")).'" class="flat maxwidth50imp" type="text" maxlength="4" id="'.$prefix.'year" name="'.$prefix.'year" value="'.$syear.'">';
4733
                }
4734
                else
4735
                {
4736
                    $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth75" id="'.$prefix.'year" name="'.$prefix.'year">';
4737
4738
                    for ($year = $syear - 5; $year < $syear + 10 ; $year++)
4739
                    {
4740
                        $retstring.='<option value="'.$year.'"'.($year == $syear ? ' selected':'').'>'.$year.'</option>';
4741
                    }
4742
                    $retstring.="</select>\n";
4743
                }
4744
                //$retstring.='</div>';
4745
            }
4746
        }
4747
4748
        if ($d && $h) $retstring.=($h==2?'<br>':' ');
4749
4750
        if ($h)
4751
        {
4752
            // Show hour
4753
            $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'hour':'').'" id="'.$prefix.'hour" name="'.$prefix.'hour">';
4754
            if ($emptyhours) $retstring.='<option value="-1">&nbsp;</option>';
4755
            for ($hour = 0; $hour < 24; $hour++)
4756
            {
4757
                if (strlen($hour) < 2) $hour = "0" . $hour;
4758
                $retstring.='<option value="'.$hour.'"'.(($hour == $shour)?' selected':'').'>'.$hour.(empty($conf->dol_optimize_smallscreen)?'':'H').'</option>';
0 ignored issues
show
Bug introduced by
The variable $shour 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...
4759
            }
4760
            $retstring.='</select>';
4761
            if ($m && empty($conf->dol_optimize_smallscreen)) $retstring.=":";
4762
        }
4763
4764
        if ($m)
4765
        {
4766
            // Show minutes
4767
            $retstring.='<select'.($disabled?' disabled':'').' class="flat valignmiddle maxwidth50 '.($fullday?$fullday.'min':'').'" id="'.$prefix.'min" name="'.$prefix.'min">';
4768
            if ($emptyhours) $retstring.='<option value="-1">&nbsp;</option>';
4769
            for ($min = 0; $min < 60 ; $min++)
4770
            {
4771
                if (strlen($min) < 2) $min = "0" . $min;
4772
                $retstring.='<option value="'.$min.'"'.(($min == $smin)?' selected':'').'>'.$min.(empty($conf->dol_optimize_smallscreen)?'':'').'</option>';
0 ignored issues
show
Bug introduced by
The variable $smin 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...
4773
            }
4774
            $retstring.='</select>';
4775
        }
4776
4777
        // Add a "Now" link
4778
        if ($conf->use_javascript_ajax && $addnowlink)
4779
        {
4780
            // Script which will be inserted in the onClick of the "Now" link
4781
            $reset_scripts = "";
4782
4783
            // Generate the date part, depending on the use or not of the javascript calendar
4784
            $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');';
4785
            $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');';
4786
            $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');';
4787
            $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');';
4788
            /*if ($usecalendar == "eldy")
4789
            {
4790
                $base=DOL_URL_ROOT.'/core/';
4791
                $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');';
4792
            }
4793
            else
4794
            {
4795
                $reset_scripts .= 'this.form.elements[\''.$prefix.'day\'].value=formatDate(new Date(), \'d\'); ';
4796
                $reset_scripts .= 'this.form.elements[\''.$prefix.'month\'].value=formatDate(new Date(), \'M\'); ';
4797
                $reset_scripts .= 'this.form.elements[\''.$prefix.'year\'].value=formatDate(new Date(), \'yyyy\'); ';
4798
            }*/
4799
            // Update the hour part
4800
            if ($h)
4801
            {
4802
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4803
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); ';
4804
                $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');';
4805
                if ($fullday) $reset_scripts .= ' } ';
4806
            }
4807
            // Update the minute part
4808
            if ($m)
4809
            {
4810
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4811
                //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); ';
4812
                $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');';
4813
                if ($fullday) $reset_scripts .= ' } ';
4814
            }
4815
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
4816
            if ($reset_scripts && empty($conf->dol_optimize_smallscreen))
4817
            {
4818
                $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonNow" type="button" name="_useless" value="now" onClick="'.$reset_scripts.'">';
4819
                $retstring.=$langs->trans("Now");
4820
                $retstring.='</button> ';
4821
            }
4822
        }
4823
4824
        // Add a "Plus one hour" link
4825
        if ($conf->use_javascript_ajax && $addplusone)
4826
        {
4827
            // Script which will be inserted in the onClick of the "Add plusone" link
4828
            $reset_scripts = "";
4829
4830
            // Generate the date part, depending on the use or not of the javascript calendar
4831
            $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(),'day').'\');';
4832
            $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(),'%d').'\');';
4833
            $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(),'%m').'\');';
4834
            $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(),'%Y').'\');';
4835
            // Update the hour part
4836
            if ($h)
4837
            {
4838
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4839
                $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date(dol_now(),'%H').'\');';
4840
                if ($fullday) $reset_scripts .= ' } ';
4841
            }
4842
            // Update the minute part
4843
            if ($m)
4844
            {
4845
                if ($fullday) $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {";
4846
                $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date(dol_now(),'%M').'\');';
4847
                if ($fullday) $reset_scripts .= ' } ';
4848
            }
4849
            // If reset_scripts is not empty, print the link with the reset_scripts in the onClick
4850
            if ($reset_scripts && empty($conf->dol_optimize_smallscreen))
4851
            {
4852
                $retstring.=' <button class="dpInvisibleButtons datenowlink" id="'.$prefix.'ButtonPlusOne" type="button" name="_useless2" value="plusone" onClick="'.$reset_scripts.'">';
4853
                $retstring.=$langs->trans("DateStartPlusOne");
4854
                $retstring.='</button> ';
4855
            }
4856
        }
4857
4858
        // Add a "Plus one hour" link
4859
        if ($conf->use_javascript_ajax && $adddateof)
4860
        {
4861
            $tmparray=dol_getdate($adddateof);
4862
            $retstring.=' - <button class="dpInvisibleButtons datenowlink" id="dateofinvoice" type="button" name="_dateofinvoice" value="now" onclick="jQuery(\'#re\').val(\''.dol_print_date($adddateof,'day').'\');jQuery(\'#reday\').val(\''.$tmparray['mday'].'\');jQuery(\'#remonth\').val(\''.$tmparray['mon'].'\');jQuery(\'#reyear\').val(\''.$tmparray['year'].'\');">'.$langs->trans("DateInvoice").'</a>';
4863
        }
4864
4865
        if (! empty($nooutput)) return $retstring;
4866
4867
        print $retstring;
4868
        return;
4869
    }
4870
4871
    /**
4872
     *	Function to show a form to select a duration on a page
4873
     *
4874
     *	@param	string	$prefix   		Prefix for input fields
4875
     *	@param  int		$iSecond  		Default preselected duration (number of seconds or '')
4876
     * 	@param	int		$disabled		Disable the combo box
4877
     * 	@param	string	$typehour		If 'select' then input hour and input min is a combo, if 'text' input hour is in text and input min is a combo
4878
     *  @param	integer	$minunderhours	If 1, show minutes selection under the hours
4879
     * 	@param	int		$nooutput		Do not output html string but return it
4880
     *  @return	string|null
4881
     */
4882
    function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0)
4883
    {
4884
    	global $langs;
4885
4886
    	$retstring='';
4887
4888
    	$hourSelected=0; $minSelected=0;
4889
4890
    	// Hours
4891
        if ($iSecond != '')
4892
        {
4893
            require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
4894
4895
            $hourSelected = convertSecondToTime($iSecond,'allhour');
4896
            $minSelected = convertSecondToTime($iSecond,'min');
4897
        }
4898
4899
        if ($typehour=='select')
4900
        {
4901
	        $retstring.='<select class="flat" name="'.$prefix.'hour"'.($disabled?' disabled':'').'>';
4902
	        for ($hour = 0; $hour < 25; $hour++)	// For a duration, we allow 24 hours
4903
	        {
4904
	            $retstring.='<option value="'.$hour.'"';
4905
	            if ($hourSelected == $hour)
4906
	            {
4907
	                $retstring.=" selected";
4908
	            }
4909
	            $retstring.=">".$hour."</option>";
4910
	        }
4911
	        $retstring.="</select>";
4912
        }
4913
        elseif ($typehour=='text')
4914
        {
4915
        	$retstring.='<input type="text" size="1" name="'.$prefix.'hour"'.($disabled?' disabled':'').' class="flat" value="'.($hourSelected?((int) $hourSelected):'').'">';
4916
        }
4917
        else return 'BadValueForParameterTypeHour';
4918
4919
        $retstring.=' '.$langs->trans('HourShort');
4920
4921
        // Minutes
4922
        if ($minunderhours) $retstring.='<br>';
4923
        else $retstring.="&nbsp;";
4924
4925
        if ($typehour=='select')
4926
        {
4927
	        $retstring.='<select class="flat" name="'.$prefix.'min"'.($disabled?' disabled':'').'>';
4928
	        for ($min = 0; $min <= 55; $min=$min+5)
4929
	        {
4930
	            $retstring.='<option value="'.$min.'"';
4931
	            if ($minSelected == $min) $retstring.=' selected';
4932
	            $retstring.='>'.$min.'</option>';
4933
	        }
4934
	        $retstring.="</select>";
4935
        }
4936
        elseif ($typehour=='text')
4937
        {
4938
        	$retstring.='<input type="text" size="1" name="'.$prefix.'min"'.($disabled?' disabled':'').' class="flat" value="'.($minSelected?((int) $minSelected):'').'">';
4939
        }
4940
        $retstring.=' '.$langs->trans('MinuteShort');
4941
        $retstring.="&nbsp;";
4942
4943
        if (! empty($nooutput)) return $retstring;
4944
4945
        print $retstring;
4946
        return;
4947
    }
4948
4949
4950
    /**
4951
     *	Return a HTML select string, built from an array of key+value.
4952
     *  Note: Do not apply langs->trans function on returned content, content may be entity encoded twice.
4953
     *
4954
     *	@param	string			$htmlname       Name of html select area. Must start with "multi" if this is a multiselect
4955
     *	@param	array			$array          Array with key+value
4956
     *	@param	string|string[]	$id             Preselected key or preselected keys for multiselect
4957
     *	@param	int				$show_empty     0 no empty value allowed, 1 or string to add an empty value into list (value is '' or '&nbsp;' if 1), <0 to add an empty value with key that is this value.
4958
     *	@param	int				$key_in_label   1 pour afficher la key dans la valeur "[key] value"
4959
     *	@param	int				$value_as_key   1 to use value as key
4960
     *	@param  string			$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
4961
     *	@param  int				$translate		Translate and encode value
4962
     * 	@param	int				$maxlen			Length maximum for labels
4963
     * 	@param	int				$disabled		Html select box is disabled
4964
     *  @param	string			$sort			'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order
4965
     *  @param	string			$morecss		Add more class to css styles
4966
     *  @param	int				$addjscombo		    Add js combo
4967
     *  @param  string          $moreparamonempty   Add more param on the empty option line. Not used if show_empty not set.
4968
     *  @param  int             $disablebademail    Check if an email is found into value and if not disable and colorize entry.
4969
     * 	@return	string							    HTML select string.
4970
     *  @see multiselectarray
4971
     */
4972
    static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0)
4973
    {
4974
        global $conf, $langs;
4975
4976
        // Do we want a multiselect ?
4977
        //$jsbeautify = 0;
4978
        //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1;
4979
		$jsbeautify = 1;
4980
4981
        if ($value_as_key) $array=array_combine($array, $array);
4982
4983
        $out='';
4984
4985
        // Add code for jquery to use multiselect
4986
        if ($addjscombo && empty($conf->dol_use_jmobile) && $jsbeautify)
4987
        {
4988
        	$minLengthToAutocomplete=0;
4989
        	$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?(constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
4990
4991
        	// Enhance with select2
4992
        	$nodatarole='';
4993
        	if ($conf->use_javascript_ajax)
4994
        	{
4995
        	    include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
4996
        	    $comboenhancement = ajax_combobox($htmlname);
4997
        	    $out.=$comboenhancement;
4998
        	    $nodatarole=($comboenhancement?' data-role="none"':'');
4999
        	}
5000
        }
5001
5002
        $out.='<select id="'.preg_replace('/^\./','',$htmlname).'" '.($disabled?'disabled ':'').'class="flat '.(preg_replace('/^\./','',$htmlname)).($morecss?' '.$morecss:'').'" name="'.preg_replace('/^\./','',$htmlname).'" '.($moreparam?$moreparam:'').'>';
5003
5004
        if ($show_empty)
5005
        {
5006
        	$textforempty=' ';
5007
        	if (! empty($conf->use_javascript_ajax)) $textforempty='&nbsp;';	// If we use ajaxcombo, we need &nbsp; here to avoid to have an empty element that is too small.
5008
            if (! is_numeric($show_empty)) $textforempty=$show_empty;
5009
        	$out.='<option class="optiongrey" '.($moreparamonempty?$moreparamonempty.' ':'').'value="'.($show_empty < 0 ? $show_empty : -1).'"'.($id == $show_empty ?' selected':'').'>'.$textforempty.'</option>'."\n";
5010
        }
5011
5012
        if (is_array($array))
5013
        {
5014
        	// Translate
5015
        	if ($translate)
5016
        	{
5017
	        	foreach($array as $key => $value)
5018
	        	{
5019
	        	    $array[$key]=$langs->trans($value);
5020
	        	}
5021
        	}
5022
5023
        	// Sort
5024
			if ($sort == 'ASC') asort($array);
5025
			elseif ($sort == 'DESC') arsort($array);
5026
5027
            foreach($array as $key => $value)
5028
            {
5029
                $disabled=''; $style='';
5030
                if (! empty($disablebademail))
5031
                {
5032
                    if (! preg_match('/&lt;.+@.+&gt;/', $value))
5033
                    {
5034
                        //$value=preg_replace('/'.preg_quote($a,'/').'/', $b, $value);
5035
                        $disabled=' disabled';
5036
                        $style=' class="warning"';
5037
                    }
5038
                }
5039
                $out.='<option value="'.$key.'"';
5040
                $out.=$style.$disabled;
5041
                if ($id != '' && $id == $key && ! $disabled) $out.=' selected';		// To preselect a value
5042
                $out.='>';
5043
5044
                if ($key_in_label)
5045
                {
5046
                    $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value));
5047
                }
5048
                else
5049
                {
5050
                    $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value);
5051
                    if ($value == '' || $value == '-') $selectOptionValue='&nbsp;';
5052
                }
5053
                //var_dump($selectOptionValue);
5054
                $out.=$selectOptionValue;
5055
                $out.="</option>\n";
5056
            }
5057
        }
5058
5059
        $out.="</select>";
5060
        return $out;
5061
    }
5062
5063
5064
    /**
5065
     *	Return a HTML select string, built from an array of key+value but content returned into select come from an Ajax call of an URL.
5066
     *  Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice.
5067
     *
5068
     *	@param	string	$htmlname       		Name of html select area
5069
     *	@param	string	$url					Url. Must return a json_encode of array(key=>array('text'=>'A text', 'url'=>'An url'), ...)
5070
     *	@param	string	$id             		Preselected key
5071
     *	@param  string	$moreparam      		Add more parameters onto the select tag
5072
     *	@param  string	$moreparamtourl 		Add more parameters onto the Ajax called URL
5073
     * 	@param	int		$disabled				Html select box is disabled
5074
     *  @param	int		$minimumInputLength		Minimum Input Length
5075
     *  @param	string	$morecss				Add more class to css styles
5076
     *  @param  int     $callurlonselect        If set to 1, some code is added so an url return by the ajax is called when value is selected.
5077
     *  @param  string  $placeholder            String to use as placeholder
5078
     *  @param  integer  $acceptdelayedhtml      1 if caller request to have html delayed content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect)
5079
     * 	@return	string   						HTML select string
5080
     */
5081
    static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0)
5082
    {
5083
        global $langs;
5084
        global $delayedhtmlcontent;
5085
5086
    	$tmpplugin='select2';
5087
5088
    	$out='<input type="text" class="'.$htmlname.($morecss?' '.$morecss:'').'" '.($moreparam?$moreparam.' ':'').'name="'.$htmlname.'">';
5089
5090
    	// TODO Use an internal dolibarr component instead of select2
5091
    	$outdelayed='<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' -->
5092
	    	<script type="text/javascript">
5093
	    	$(document).ready(function () {
5094
5095
    	        '.($callurlonselect ? 'var saveRemoteData = [];':'').'
5096
5097
                $(".'.$htmlname.'").select2({
5098
			    	ajax: {
5099
				    	dir: "ltr",
5100
				    	url: "'.$url.'",
5101
				    	dataType: \'json\',
5102
				    	delay: 250,
5103
				    	data: function (searchTerm, pageNumber, context) {
5104
				    		return {
5105
						    	q: searchTerm, // search term
5106
				    			page: pageNumber
5107
				    		};
5108
			    		},
5109
			    		results: function (remoteData, pageNumber, query) {
5110
			    			console.log(remoteData);
5111
				    	    saveRemoteData = remoteData;
5112
				    	    /* format json result for select2 */
5113
				    	    result = []
5114
				    	    $.each( remoteData, function( key, value ) {
5115
				    	       result.push({id: key, text: value.text});
5116
                            });
5117
			    			//return {results:[{id:\'none\', text:\'aa\'}, {id:\'rrr\', text:\'Red\'},{id:\'bbb\', text:\'Search a into projects\'}], more:false}
5118
			    			return {results: result, more:false}
5119
    					},
5120
			    		/*processResults: function (data, page) {
5121
			    			// parse the results into the format expected by Select2.
5122
			    			// since we are using custom formatting functions we do not need to
5123
			    			// alter the remote JSON data
5124
			    			console.log(data);
5125
			    			return {
5126
			    				results: data.items
5127
			    			};
5128
			    		},*/
5129
			    		cache: true
5130
			    	},
5131
			        dropdownCssClass: "css-'.$htmlname.'",
5132
				    placeholder: "'.dol_escape_js($placeholder).'",
5133
			    	escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
5134
			    	minimumInputLength: '.$minimumInputLength.',
5135
			        formatResult: function(result, container, query, escapeMarkup) {
5136
                        return escapeMarkup(result.text);
5137
                    }
5138
			    });
5139
5140
                '.($callurlonselect ? '
5141
                $(".'.$htmlname.'").change(function() {
5142
			    	var selected = $(".'.$htmlname.'").select2("val");
5143
			        $(".'.$htmlname.'").select2("val","");  /* reset visible combo value */
5144
    			    $.each( saveRemoteData, function( key, value ) {
5145
    				        if (key == selected)
5146
    			            {
5147
    			                 console.log("Do a redirect into selectArrayAjax to "+value.url)
5148
    			                 location.assign(value.url);
5149
    			            }
5150
                    });
5151
    			});' : '' ) . '
5152
5153
    	   });
5154
	       </script>';
5155
5156
		if ($acceptdelayedhtml)
5157
		{
5158
		    $delayedhtmlcontent.=$outdelayed;
5159
		}
5160
		else
5161
		{
5162
		    $out.=$outdelayed;
5163
		}
5164
		return $out;
5165
    }
5166
5167
    /**
5168
     *	Show a multiselect form from an array.
5169
     *
5170
     *	@param	string	$htmlname		Name of select
5171
     *	@param	array	$array			Array with key+value
5172
     *	@param	array	$selected		Array with key+value preselected
5173
     *	@param	int		$key_in_label   1 pour afficher la key dans la valeur "[key] value"
5174
     *	@param	int		$value_as_key   1 to use value as key
5175
     *	@param  string	$morecss        Add more css style
5176
     *	@param  int		$translate		Translate and encode value
5177
     *  @param	int		$width			Force width of select box. May be used only when using jquery couch. Example: 250, 95%
5178
     *  @param	string	$moreattrib		Add more options on select component. Example: 'disabled'
5179
     *  @param	string	$elemtype		Type of element we show ('category', ...)
5180
     *	@return	string					HTML multiselect string
5181
     *  @see selectarray
5182
     */
5183
    static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='',$elemtype='')
5184
    {
5185
    	global $conf, $langs;
5186
5187
    	$out = '';
5188
5189
    	// Add code for jquery to use multiselect
5190
    	if (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT'))
5191
    	{
5192
    		$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
5193
   			$out.='<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' -->
5194
    			<script type="text/javascript">
5195
	    			function formatResult(record) {'."\n";
5196
						if ($elemtype == 'category')
5197
						{
5198
							$out.='	//return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> <a href="'.DOL_URL_ROOT.'/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
5199
								  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
5200
						}
5201
						else
5202
						{
5203
							$out.='return record.text;';
5204
						}
5205
			$out.= '	};
5206
    				function formatSelection(record) {'."\n";
5207
						if ($elemtype == 'category')
5208
						{
5209
							$out.='	//return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> <a href="'.DOL_URL_ROOT.'/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
5210
								  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
5211
						}
5212
						else
5213
						{
5214
							$out.='return record.text;';
5215
						}
5216
			$out.= '	};
5217
	    			$(document).ready(function () {
5218
    					$(\'#'.$htmlname.'\').'.$tmpplugin.'({
5219
    						dir: \'ltr\',
5220
							// Specify format function for dropdown item
5221
							formatResult: formatResult,
5222
    					 	templateResult: formatResult,		/* For 4.0 */
5223
							// Specify format function for selected item
5224
							formatSelection: formatSelection,
5225
    					 	templateResult: formatSelection		/* For 4.0 */
5226
    					});
5227
    				});
5228
    			</script>';
5229
    	}
5230
5231
    	// Try also magic suggest
5232
5233
    	// Add data-role="none" to disable jmobile decoration
5234
		$out .= '<select data-role="none" id="'.$htmlname.'" class="multiselect'.($morecss?' '.$morecss:'').'" multiple name="'.$htmlname.'[]"'.($moreattrib?' '.$moreattrib:'').($width?' style="width: '.(preg_match('/%/',$width)?$width:$width.'px').'"':'').'>'."\n";
5235
    	if (is_array($array) && ! empty($array))
5236
    	{
5237
    		if ($value_as_key) $array=array_combine($array, $array);
5238
5239
    		if (! empty($array))
5240
    		{
5241
    			foreach ($array as $key => $value)
5242
    			{
5243
    				$out.= '<option value="'.$key.'"';
5244
    				if (is_array($selected) && ! empty($selected) && in_array($key, $selected) && !empty($key))
5245
    				{
5246
    					$out.= ' selected';
5247
    				}
5248
    				$out.= '>';
5249
5250
    				$newval = ($translate ? $langs->trans($value) : $value);
5251
    				$newval = ($key_in_label ? $key.' - '.$newval : $newval);
5252
    				$out.= dol_htmlentitiesbr($newval);
5253
    				$out.= '</option>'."\n";
5254
    			}
5255
    		}
5256
    	}
5257
    	$out.= '</select>'."\n";
5258
5259
    	return $out;
5260
    }
5261
5262
5263
    /**
5264
     *	Show a multiselect form from an array.
5265
     *
5266
     *	@param	string	$htmlname		Name of select
5267
     *	@param	array	$array			Array with array of fields we could show. This array may be modified according to setup of user.
5268
     *  @param  string  $varpage        Id of context for page. Can be set with $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
5269
     *	@return	string					HTML multiselect string
5270
     *  @see selectarray
5271
     */
5272
    static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage)
5273
    {
5274
        global $conf,$user;
5275
5276
        if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return '';
5277
5278
        $tmpvar="MAIN_SELECTEDFIELDS_".$varpage;
5279
        if (! empty($user->conf->$tmpvar))
5280
        {
5281
            $tmparray=explode(',', $user->conf->$tmpvar);
5282
            foreach($array as $key => $val)
5283
            {
5284
                //var_dump($key);
5285
                //var_dump($tmparray);
5286
                if (in_array($key, $tmparray)) $array[$key]['checked']=1;
5287
                else $array[$key]['checked']=0;
5288
            }
5289
        }
5290
        //var_dump($array);
5291
5292
        $lis='';
5293
        $listcheckedstring='';
5294
5295
        foreach($array as $key => $val)
5296
        {
5297
           /* var_dump($val);
5298
            var_dump(array_key_exists('enabled', $val));
5299
            var_dump(!$val['enabled']);*/
5300
           if (array_key_exists('enabled', $val) && isset($val['enabled']) && ! $val['enabled'])
5301
           {
5302
               unset($array[$key]);     // We don't want this field
5303
               continue;
5304
           }
5305
           if ($val['label'])
5306
	       {
5307
	           $lis.='<li><input type="checkbox" value="'.$key.'"'.(empty($val['checked'])?'':' checked="checked"').'/>'.dol_escape_htmltag($val['label']).'</li>';
5308
	           $listcheckedstring.=(empty($val['checked'])?'':$key.',');
5309
	       }
5310
        }
5311
5312
        $out ='<!-- Component multiSelectArrayWithCheckbox '.$htmlname.' -->
5313
5314
        <dl class="dropdown">
5315
            <dt>
5316
            <a href="#">
5317
              '.img_picto('','list').'
5318
            </a>
5319
            <input type="hidden" class="'.$htmlname.'" name="'.$htmlname.'" value="'.$listcheckedstring.'">
5320
            </dt>
5321
            <dd class="dropowndd">
5322
                <div class="multiselectcheckbox'.$htmlname.'">
5323
                    <ul class="ul'.$htmlname.'">
5324
                    '.$lis.'
5325
                    </ul>
5326
                </div>
5327
            </dd>
5328
        </dl>
5329
5330
        <script type="text/javascript">
5331
          jQuery(document).ready(function () {
5332
              $(\'.multiselectcheckbox'.$htmlname.' input[type="checkbox"]\').on(\'click\', function () {
5333
                  console.log("A new field was added/removed")
5334
                  $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\')
5335
                  var title = $(this).val() + ",";
5336
                  if ($(this).is(\':checked\')) {
5337
                      $(\'.'.$htmlname.'\').val(title + $(\'.'.$htmlname.'\').val());
5338
                  }
5339
                  else {
5340
                      $(\'.'.$htmlname.'\').val( $(\'.'.$htmlname.'\').val().replace(title, \'\') )
5341
                  }
5342
                  // Now, we submit page
5343
                  $(this).parents(\'form:first\').submit();
5344
              });
5345
           });
5346
        </script>
5347
5348
        ';
5349
        return $out;
5350
    }
5351
5352
	/**
5353
	 * 	Render list of categories linked to object with id $id and type $type
5354
	 *
5355
	 * 	@param		int		$id				Id of object
5356
 	 * 	@param		string	$type			Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated.
5357
 	 *  @param		int		$rendermode		0=Default, use multiselect. 1=Emulate multiselect (recommended)
5358
	 * 	@return		string					String with categories
5359
	 */
5360
	function showCategories($id, $type, $rendermode=0)
5361
	{
5362
		global $db;
5363
5364
		include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
5365
5366
		$cat = new Categorie($db);
5367
		$categories = $cat->containing($id, $type);
5368
5369
		if ($rendermode == 1)
5370
		{
5371
			$toprint = array();
5372
			foreach($categories as $c)
5373
			{
5374
				$ways = $c->print_all_ways();       // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text
5375
				foreach($ways as $way)
5376
				{
5377
					$toprint[] = '<li class="select2-search-choice-dolibarr noborderoncategories"'.($c->color?' style="background: #'.$c->color.';"':' style="background: #aaa"').'>'.img_object('','category').' '.$way.'</li>';
5378
				}
5379
			}
5380
			return '<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
5381
		}
5382
5383
		if ($rendermode == 0)
5384
		{
5385
			$cate_arbo = $this->select_all_categories($type, '', 'parent', 64, 0, 1);
5386
			foreach($categories as $c) {
5387
				$arrayselected[] = $c->id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arrayselected was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arrayselected = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
5388
			}
5389
5390
			return $this->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%', 'disabled', 'category');
0 ignored issues
show
Bug introduced by
The variable $arrayselected 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...
5391
		}
5392
5393
		return 'ErrorBadValueForParameterRenderMode';	// Should not happened
5394
	}
5395
5396
5397
    /**
5398
     *  Show linked object block.
5399
     *
5400
     *  @param	CommonObject	$object		      Object we want to show links to
5401
     *  @param  string          $morehtmlright    More html to show on right of title
5402
     *  @return	int							      <0 if KO, >=0 if OK
5403
     */
5404
    function showLinkedObjectBlock($object, $morehtmlright='')
5405
    {
5406
        global $conf,$langs,$hookmanager;
5407
        global $bc;
5408
5409
        $object->fetchObjectLinked();
5410
5411
        // Bypass the default method
5412
        $hookmanager->initHooks(array('commonobject'));
5413
        $parameters=array();
5414
        $reshook=$hookmanager->executeHooks('showLinkedObjectBlock',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
0 ignored issues
show
Bug introduced by
The variable $action 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...
5415
5416
        if (empty($reshook))
5417
        {
5418
        	$nbofdifferenttypes = count($object->linkedObjects);
5419
5420
        	print '<br>';
5421
            print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '');
5422
5423
            print '<table class="noborder allwidth">';
5424
5425
            print '<tr class="liste_titre">';
5426
            print '<td>'.$langs->trans("Type").'</td>';
5427
            print '<td>'.$langs->trans("Ref").'</td>';
5428
            print '<td align="center"></td>';
5429
            print '<td align="center">'.$langs->trans("Date").'</td>';
5430
            print '<td align="right">'.$langs->trans("AmountHTShort").'</td>';
5431
            print '<td align="right">'.$langs->trans("Status").'</td>';
5432
            print '<td></td>';
5433
            print '</tr>';
5434
5435
            $nboftypesoutput=0;
5436
5437
        	foreach($object->linkedObjects as $objecttype => $objects)
5438
        	{
5439
        		$tplpath = $element = $subelement = $objecttype;
5440
5441
        		if ($objecttype != 'supplier_proposal' && preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs))
5442
        		{
5443
        			$element = $regs[1];
5444
        			$subelement = $regs[2];
5445
        			$tplpath = $element.'/'.$subelement;
5446
        		}
5447
        		$tplname='linkedobjectblock';
5448
5449
        		// To work with non standard path
5450
        		if ($objecttype == 'facture')          {
5451
        			$tplpath = 'compta/'.$element;
5452
        			if (empty($conf->facture->enabled)) continue;	// Do not show if module disabled
5453
        		}
5454
        	    else if ($objecttype == 'facturerec')          {
5455
        			$tplpath = 'compta/facture';
5456
        			$tplname = 'linkedobjectblockForRec';
5457
        			if (empty($conf->facture->enabled)) continue;	// Do not show if module disabled
5458
        		}
5459
        		else if ($objecttype == 'propal')           {
5460
        			$tplpath = 'comm/'.$element;
5461
        			if (empty($conf->propal->enabled)) continue;	// Do not show if module disabled
5462
        		}
5463
        		else if ($objecttype == 'supplier_proposal')           {
5464
        			if (empty($conf->supplier_proposal->enabled)) continue;	// Do not show if module disabled
5465
        		}
5466
        		else if ($objecttype == 'shipping' || $objecttype == 'shipment') {
5467
        			$tplpath = 'expedition';
5468
        			if (empty($conf->expedition->enabled)) continue;	// Do not show if module disabled
5469
        		}
5470
        		else if ($objecttype == 'delivery')         {
5471
        			$tplpath = 'livraison';
5472
        			if (empty($conf->expedition->enabled)) continue;	// Do not show if module disabled
5473
        		}
5474
        		else if ($objecttype == 'invoice_supplier') {
5475
        			$tplpath = 'fourn/facture';
5476
        		}
5477
        		else if ($objecttype == 'order_supplier')   {
5478
        			$tplpath = 'fourn/commande';
5479
        		}
5480
        		else if ($objecttype == 'expensereport')   {
5481
        			$tplpath = 'expensereport';
5482
        		}
5483
        		else if ($objecttype == 'subscription')   {
5484
        		    $tplpath = 'adherents';
5485
        		}
5486
5487
                global $linkedObjectBlock;
5488
        		$linkedObjectBlock = $objects;
5489
5490
5491
        		// Output template part (modules that overwrite templates must declare this into descriptor)
5492
        		$dirtpls=array_merge($conf->modules_parts['tpl'],array('/'.$tplpath.'/tpl'));
5493
        		foreach($dirtpls as $reldir)
5494
        		{
5495
        		    if ($nboftypesoutput == ($nbofdifferenttypes - 1))    // No more type to show after
5496
        		    {
5497
        		        global $noMoreLinkedObjectBlockAfter;
5498
        		        $noMoreLinkedObjectBlockAfter=1;
5499
        		    }
5500
5501
                    $res=@include dol_buildpath($reldir.'/'.$tplname.'.tpl.php');
5502
        			if ($res)
5503
        			{
5504
        			    $nboftypesoutput++;
5505
        			    break;
5506
        			}
5507
        		}
5508
        	}
5509
5510
        	if (! $nboftypesoutput)
5511
        	{
5512
        	    print '<tr><td class="opacitymedium" colspan="7">'.$langs->trans("None").'</td></tr>';
5513
        	}
5514
5515
        	print '</table>';
5516
5517
        	return $nbofdifferenttypes;
5518
        }
5519
    }
5520
5521
    /**
5522
     *  Show block with links to link to other objects.
5523
     *
5524
     *  @param	CommonObject	$object				Object we want to show links to
5525
     *  @param	array			$restrictlinksto	Restrict links to some elements, for exemple array('order') or array('supplier_order'). null or array() if no restriction.
5526
     *  @param	array			$excludelinksto		Do not show links of this type, for exemple array('order') or array('supplier_order'). null or array() if no exclusion.
5527
     *  @return	string								<0 if KO, >0 if OK
5528
     */
5529
    function showLinkToObjectBlock($object, $restrictlinksto=array(), $excludelinksto=array())
5530
    {
5531
        global $conf, $langs, $hookmanager;
5532
        global $bc;
5533
5534
		$linktoelem='';
5535
		$linktoelemlist='';
5536
5537
		if (! is_object($object->thirdparty)) $object->fetch_thirdparty();
5538
5539
		$possiblelinks=array(
5540
			'propal'=>array('enabled'=>$conf->propal->enabled, 'perms'=>1, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5541
			'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5542
			'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.facnumber as ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5543
			'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5544
			'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5545
			'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5546
			'order_supplier'=>array('enabled'=>$conf->fournisseur->commande->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id),
5547
			'invoice_supplier'=>array('enabled'=>$conf->fournisseur->facture->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc = ".$object->thirdparty->id)
5548
		);
5549
5550
		global $action;
5551
5552
		// Can complet the possiblelink array
5553
		$hookmanager->initHooks(array('commonobject'));
5554
		$parameters=array();
5555
		$reshook=$hookmanager->executeHooks('showLinkToObjectBlock',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
5556
		if (empty($reshook))
5557
		{
5558
		    if (is_array($hookmanager->resArray) && count($hookmanager->resArray))
5559
		    {
5560
		        $possiblelinks=array_merge($possiblelinks, $hookmanager->resArray);
5561
		    }
5562
		}
5563
		else if ($reshook > 0)
5564
		{
5565
		    if (is_array($hookmanager->resArray) && count($hookmanager->resArray))
5566
		    {
5567
                $possiblelinks=$hookmanager->resArray;
5568
		    }
5569
		}
5570
5571
		foreach($possiblelinks as $key => $possiblelink)
5572
		{
5573
			$num = 0;
5574
5575
			if (empty($possiblelink['enabled'])) continue;
5576
5577
			if (! empty($possiblelink['perms']) && (empty($restrictlinksto) || in_array($key, $restrictlinksto)) && (empty($excludelinksto) || ! in_array($key, $excludelinksto)))
5578
			{
5579
				print '<div id="'.$key.'list"'.(empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)?' style="display:none"':'').'>';
5580
				$sql = $possiblelink['sql'];
5581
5582
				$resqllist = $this->db->query($sql);
5583
				if ($resqllist)
5584
				{
5585
					$num = $this->db->num_rows($resqllist);
5586
					$i = 0;
5587
5588
					print '<br><form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formlinked'.$key.'">';
5589
					print '<input type="hidden" name="id" value="'.$object->id.'">';
5590
					print '<input type="hidden" name="action" value="addlink">';
5591
					print '<input type="hidden" name="addlink" value="'.$key.'">';
5592
					print '<table class="noborder">';
5593
					print '<tr class="liste_titre">';
5594
					print '<td class="nowrap"></td>';
5595
					print '<td align="center">' . $langs->trans("Ref") . '</td>';
5596
					print '<td align="left">' . $langs->trans("RefCustomer") . '</td>';
5597
					print '<td align="right">' . $langs->trans("AmountHTShort") . '</td>';
5598
					print '<td align="left">' . $langs->trans("Company") . '</td>';
5599
					print '</tr>';
5600
					while ($i < $num)
5601
					{
5602
						$objp = $this->db->fetch_object($resqlorderlist);
0 ignored issues
show
Bug introduced by
The variable $resqlorderlist 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...
5603
5604
						$var = ! $var;
0 ignored issues
show
Bug introduced by
The variable $var 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...
5605
						print '<tr ' . $bc [$var] . '>';
5606
						print '<td aling="left">';
5607
						print '<input type="radio" name="idtolinkto" value=' . $objp->rowid . '>';
5608
						print '</td>';
5609
						print '<td align="center">' . $objp->ref . '</td>';
5610
						print '<td>' . $objp->ref_client . '</td>';
5611
						print '<td align="right">' . price($objp->total_ht) . '</td>';
5612
						print '<td>' . $objp->name . '</td>';
5613
						print '</tr>';
5614
						$i++;
5615
					}
5616
					print '</table>';
5617
					print '<div class="center"><input type="submit" class="button valignmiddle" value="' . $langs->trans('ToLink') . '">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" class="button" name="cancel" value="' . $langs->trans('Cancel') . '"></div>';
5618
5619
					print '</form>';
5620
					$this->db->free($resqllist);
5621
				} else {
5622
					dol_print_error($this->db);
5623
				}
5624
				print '</div>';
5625
				if ($num > 0)
5626
				{
5627
				}
5628
5629
				//$linktoelem.=($linktoelem?' &nbsp; ':'');
5630
				if ($num > 0) $linktoelemlist.='<li><a href="#linkto'.$key.'" class="linkto dropdowncloseonclick" rel="'.$key.'">' . $langs->trans($possiblelink['label']) .' ('.$num.')</a></li>';
5631
				//else $linktoelem.=$langs->trans($possiblelink['label']);
5632
				else $linktoelemlist.='<li><span class="linktodisabled">' . $langs->trans($possiblelink['label']) . ' (0)</span></li>';
5633
			}
5634
		}
5635
5636
		if ($linktoelemlist)
5637
		{
5638
    		$linktoelem='
5639
    		<dl class="dropdown" id="linktoobjectname">
5640
    		<dt><a href="#linktoobjectname">'.$langs->trans("LinkTo").'...</a></dt>
5641
    		<dd>
5642
    		<div class="multiselectlinkto">
5643
    		<ul class="ulselectedfields">'.$linktoelemlist.'
5644
    		</ul>
5645
    		</div>
5646
    		</dd>
5647
    		</dl>';
5648
		}
5649
		else
5650
		{
5651
		    $linktoelem='';
5652
		}
5653
5654
		print '<!-- Add js to show linkto box -->
5655
				<script type="text/javascript" language="javascript">
5656
				jQuery(document).ready(function() {
5657
					jQuery(".linkto").click(function() {
5658
						console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\'));
5659
					    jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle();
5660
						jQuery(this).toggle();
5661
					});
5662
				});
5663
				</script>
5664
		';
5665
5666
		return $linktoelem;
5667
    }
5668
5669
    /**
5670
     *	Return an html string with a select combo box to choose yes or no
5671
     *
5672
     *	@param	string		$htmlname		Name of html select field
5673
     *	@param	string		$value			Pre-selected value
5674
     *	@param	int			$option			0 return yes/no, 1 return 1/0
5675
     *	@param	bool		$disabled		true or false
5676
     *  @param	int      	$useempty		1=Add empty line
5677
     *	@return	string						See option
5678
     */
5679
    function selectyesno($htmlname,$value='',$option=0,$disabled=false,$useempty='')
5680
    {
5681
        global $langs;
5682
5683
        $yes="yes"; $no="no";
5684
        if ($option)
5685
        {
5686
            $yes="1";
5687
            $no="0";
5688
        }
5689
5690
        $disabled = ($disabled ? ' disabled' : '');
5691
5692
        $resultyesno = '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'"'.$disabled.'>'."\n";
5693
        if ($useempty) $resultyesno .= '<option value="-1"'.(($value < 0)?' selected':'').'></option>'."\n";
5694
        if (("$value" == 'yes') || ($value == 1))
5695
        {
5696
            $resultyesno .= '<option value="'.$yes.'" selected>'.$langs->trans("Yes").'</option>'."\n";
5697
            $resultyesno .= '<option value="'.$no.'">'.$langs->trans("No").'</option>'."\n";
5698
        }
5699
        else
5700
       {
5701
       		$selected=(($useempty && $value != '0' && $value != 'no')?'':' selected');
5702
            $resultyesno .= '<option value="'.$yes.'">'.$langs->trans("Yes").'</option>'."\n";
5703
            $resultyesno .= '<option value="'.$no.'"'.$selected.'>'.$langs->trans("No").'</option>'."\n";
5704
        }
5705
        $resultyesno .= '</select>'."\n";
5706
        return $resultyesno;
5707
    }
5708
5709
5710
5711
    /**
5712
     *  Return list of export templates
5713
     *
5714
     *  @param	string	$selected          Id modele pre-selectionne
5715
     *  @param  string	$htmlname          Name of HTML select
5716
     *  @param  string	$type              Type of searched templates
5717
     *  @param  int		$useempty          Affiche valeur vide dans liste
5718
     *  @return	void
5719
     */
5720
    function select_export_model($selected='',$htmlname='exportmodelid',$type='',$useempty=0)
5721
    {
5722
5723
        $sql = "SELECT rowid, label";
5724
        $sql.= " FROM ".MAIN_DB_PREFIX."export_model";
5725
        $sql.= " WHERE type = '".$type."'";
5726
        $sql.= " ORDER BY rowid";
5727
        $result = $this->db->query($sql);
5728
        if ($result)
5729
        {
5730
            print '<select class="flat" name="'.$htmlname.'">';
5731
            if ($useempty)
5732
            {
5733
                print '<option value="-1">&nbsp;</option>';
5734
            }
5735
5736
            $num = $this->db->num_rows($result);
5737
            $i = 0;
5738
            while ($i < $num)
5739
            {
5740
                $obj = $this->db->fetch_object($result);
5741
                if ($selected == $obj->rowid)
5742
                {
5743
                    print '<option value="'.$obj->rowid.'" selected>';
5744
                }
5745
                else
5746
                {
5747
                    print '<option value="'.$obj->rowid.'">';
5748
                }
5749
                print $obj->label;
5750
                print '</option>';
5751
                $i++;
5752
            }
5753
            print "</select>";
5754
        }
5755
        else {
5756
            dol_print_error($this->db);
5757
        }
5758
    }
5759
5760
    /**
5761
     *    Return a HTML area with the reference of object and a navigation bar for a business object
5762
     *    To add a particular filter on select, you must set $object->next_prev_filter to SQL criteria.
5763
     *
5764
     *    @param	object	$object			Object to show.
5765
     *    @param	string	$paramid   		Name of parameter to use to name the id into the URL next/previous link.
5766
     *    @param	string	$morehtml  		More html content to output just before the nav bar.
5767
     *    @param	int		$shownav	  	Show Condition (navigation is shown if value is 1).
5768
     *    @param	string	$fieldid   		Name of field id into database to use for select next and previous (we make the select max and min on this field).
5769
     *    @param	string	$fieldref   	Name of field ref of object (object->ref) to show or 'none' to not show ref.
5770
     *    @param	string	$morehtmlref  	More html to show after ref.
5771
     *    @param	string	$moreparam  	More param to add in nav link url. Must start with '&...'.
5772
     *	  @param	int		$nodbprefix		Do not include DB prefix to forge table name.
5773
     *	  @param	string	$morehtmlleft	More html code to show before ref.
5774
     *	  @param	string	$morehtmlstatus	More html code to show under navigation arrows (status place).
5775
     *	  @param	string	$morehtmlright	More html code to show after ref.
5776
     * 	  @return	string    				Portion HTML with ref + navigation buttons
5777
     */
5778
    function showrefnav($object,$paramid,$morehtml='',$shownav=1,$fieldid='rowid',$fieldref='ref',$morehtmlref='',$moreparam='',$nodbprefix=0,$morehtmlleft='',$morehtmlstatus='',$morehtmlright='')
5779
    {
5780
    	global $langs,$conf;
5781
5782
    	$ret='';
5783
        if (empty($fieldid))  $fieldid='rowid';
5784
        if (empty($fieldref)) $fieldref='ref';
5785
5786
        //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam";
5787
        $object->load_previous_next_ref((isset($object->next_prev_filter)?$object->next_prev_filter:''),$fieldid,$nodbprefix);
5788
        
5789
        $navurl = $_SERVER["PHP_SELF"];
5790
        // Special case for project/task page
5791
        if ($paramid == 'project_ref')
5792
        {
5793
            $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document).php/','/tasks.php',$navurl);
5794
            $paramid='ref';
5795
        }
5796
        $previous_ref = $object->ref_previous?'<a data-role="button" data-icon="arrow-l" data-iconpos="left" href="'.$navurl.'?'.$paramid.'='.urlencode($object->ref_previous).$moreparam.'">'.(($conf->dol_use_jmobile != 4)?'&lt;':'&nbsp;').'</a>':'<span class="inactive">'.(($conf->dol_use_jmobile != 4)?'&lt;':'&nbsp;').'</span>';
5797
        $next_ref     = $object->ref_next?'<a data-role="button" data-icon="arrow-r" data-iconpos="right" href="'.$navurl.'?'.$paramid.'='.urlencode($object->ref_next).$moreparam.'">'.(($conf->dol_use_jmobile != 4)?'&gt;':'&nbsp;').'</a>':'<span class="inactive">'.(($conf->dol_use_jmobile != 4)?'&gt;':'&nbsp;').'</span>';
5798
5799
        //print "xx".$previous_ref."x".$next_ref;
5800
        $ret.='<!-- Start banner content --><div style="vertical-align: middle">';
5801
5802
        // Right part of banner
5803
		if ($morehtmlright) $ret.='<div class="inline-block floatleft">'.$morehtmlright.'</div>';
5804
5805
        if ($previous_ref || $next_ref || $morehtml)
5806
        {
5807
        	$ret.='<div class="pagination"><ul>';
5808
        }
5809
        if ($morehtml)
5810
        {
5811
            $ret.='<li class="noborder litext">'.$morehtml.'</li>';
5812
        }
5813
        if ($shownav && ($previous_ref || $next_ref))
5814
        {
5815
            $ret.='<li class="pagination">'.$previous_ref.'</li>';
5816
            $ret.='<li class="pagination">'.$next_ref.'</li>';
5817
        }
5818
        if ($previous_ref || $next_ref || $morehtml)
5819
        {
5820
            $ret.='</ul></div>';
5821
        }
5822
		if ($morehtmlstatus) $ret.='<div class="statusref">'.$morehtmlstatus.'</div>';
5823
5824
        // Left part of banner
5825
		if ($morehtmlleft)
5826
		{
5827
		    if ($conf->browser->layout == 'phone') $ret.='<div class="floatleft">'.$morehtmlleft.'</div>';    // class="center" to have photo in middle
5828
		    else $ret.='<div class="inline-block floatleft">'.$morehtmlleft.'</div>';
5829
		}
5830
5831
		//if ($conf->browser->layout == 'phone') $ret.='<div class="clearboth"></div>';
5832
		$ret.='<div class="inline-block floatleft valignmiddle refid'.(($shownav && ($previous_ref || $next_ref))?' refidpadding':'').'">';
5833
5834
		// For thirdparty, contact, user, member, the ref is the id, so we show something else
5835
		if ($object->element == 'societe')
5836
		{
5837
		    $ret.=dol_htmlentities($object->name);
5838
		}
5839
		else if (in_array($object->element, array('contact', 'user', 'member')))
5840
		{
5841
		    $ret.=dol_htmlentities($object->getFullName($langs));
5842
		}
5843
		else if ($fieldref != 'none') $ret.=dol_htmlentities($object->$fieldref);
5844
		if ($morehtmlref)
5845
		{
5846
		    $ret.=' '.$morehtmlref;
5847
		}
5848
		$ret.='</div>';
5849
5850
		$ret.='</div><!-- End banner content -->';
5851
5852
        return $ret;
5853
    }
5854
5855
5856
    /**
5857
     *    	Return HTML code to output a barcode
5858
     *
5859
     *     	@param	Object	$object		Object containing data to retrieve file name
5860
     * 		@param	int		$width			Width of photo
5861
     * 	  	@return string    				HTML code to output barcode
5862
     */
5863
    function showbarcode(&$object,$width=100)
5864
    {
5865
        global $conf;
5866
5867
        //Check if barcode is filled in the card
5868
        if (empty($object->barcode)) return '';
5869
5870
        // Complete object if not complete
5871
        if (empty($object->barcode_type_code) || empty($object->barcode_type_coder))
5872
        {
5873
        	$result = $object->fetch_barcode();
5874
            //Check if fetch_barcode() failed
5875
        	if ($result < 1) return '<!-- ErrorFetchBarcode -->';
5876
        }
5877
5878
        // Barcode image
5879
        $url=DOL_URL_ROOT.'/viewimage.php?modulepart=barcode&generator='.urlencode($object->barcode_type_coder).'&code='.urlencode($object->barcode).'&encoding='.urlencode($object->barcode_type_code);
5880
        $out ='<!-- url barcode = '.$url.' -->';
5881
        $out.='<img src="'.$url.'">';
5882
        return $out;
5883
    }
5884
5885
    /**
5886
     *    	Return HTML code to output a photo
5887
     *
5888
     *    	@param	string		$modulepart			Key to define module concerned ('societe', 'userphoto', 'memberphoto')
5889
     *     	@param  object		$object				Object containing data to retrieve file name
5890
     * 		@param	int			$width				Width of photo
5891
     * 		@param	int			$height				Height of photo (auto if 0)
5892
     * 		@param	int			$caneditfield		Add edit fields
5893
     * 		@param	string		$cssclass			CSS name to use on img for photo
5894
     * 		@param	string		$imagesize		    'mini', 'small' or '' (original)
5895
     *      @param  int         $addlinktofullsize  Add link to fullsize image
5896
     *      @param  int         $cache              1=Accept to use image in cache
5897
     * 	  	@return string    						HTML code to output photo
5898
     */
5899
    static function showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0)
5900
    {
5901
        global $conf,$langs;
5902
5903
        $entity = (! empty($object->entity) ? $object->entity : $conf->entity);
5904
        $id = (! empty($object->id) ? $object->id : $object->rowid);
5905
5906
        $ret='';$dir='';$file='';$originalfile='';$altfile='';$email='';
5907
        if ($modulepart=='societe')
5908
        {
5909
            $dir=$conf->societe->multidir_output[$entity];
5910
            if (! empty($object->logo))
5911
            {
5912
                if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_mini');             // getImageFileNameForSize include the thumbs
5913
                else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.getImageFileNameForSize($object->logo, '_small');
5914
                else $file=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo;
5915
                $originalfile=get_exdir(0, 0, 0, 0, $object, 'thirdparty').'/logos/'.$object->logo;
5916
            }
5917
            $email=$object->email;
5918
        }
5919
        else if ($modulepart=='contact')
5920
        {
5921
            $dir=$conf->societe->multidir_output[$entity].'/contact';
5922
            if (! empty($object->photo))
5923
            {
5924
                if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_mini');
5925
                else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.getImageFileNameForSize($object->photo, '_small');
5926
                else $file=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo;
5927
                $originalfile=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo;
5928
            }
5929
            $email=$object->email;
5930
        }
5931
        else if ($modulepart=='userphoto')
5932
        {
5933
            $dir=$conf->user->dir_output;
5934
            if (! empty($object->photo))
5935
            {
5936
                if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_mini');
5937
                else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, 'user').getImageFileNameForSize($object->photo, '_small');
5938
                else $file=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo;
5939
                $originalfile=get_exdir($id, 2, 0, 0, $object, 'user').$object->photo;
5940
            }
5941
            if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
5942
            $email=$object->email;
5943
        }
5944
        else if ($modulepart=='memberphoto')
5945
        {
5946
            $dir=$conf->adherent->dir_output;
5947
            if (! empty($object->photo))
5948
            {
5949
                if ((string) $imagesize == 'mini') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_mini');
5950
                else if ((string) $imagesize == 'small') $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.getImageFileNameForSize($object->photo, '_small');
5951
                else $file=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo;
5952
                $originalfile=get_exdir(0, 0, 0, 0, $object, 'member').'photos/'.$object->photo;
5953
            }
5954
            if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
5955
            $email=$object->email;
5956
        }
5957
        else
5958
        {
5959
        	$dir=$conf->$modulepart->dir_output;
5960
        	if (! empty($object->photo))
5961
        	{
5962
                if ((string) $imagesize == 'mini') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_mini');
5963
                else if ((string) $imagesize == 'small') $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.getImageFileNameForSize($object->photo, '_small');
5964
        	    else $file=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo;
5965
        	    $originalfile=get_exdir($id, 2, 0, 0, $object, $modulepart).'photos/'.$object->photo;
5966
        	}
5967
        	if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
5968
        	$email=$object->email;
5969
        }
5970
5971
        if ($dir)
5972
        {
5973
            if ($file && file_exists($dir."/".$file))
5974
            {
5975
                if ($addlinktofullsize)
5976
                {
5977
                    $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile);
5978
                    if ($urladvanced) $ret.='<a href="'.$urladvanced.'">';
5979
                    else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">';
5980
                }
5981
                $ret.='<img alt="Photo" id="photologo'.(preg_replace('/[^a-z]/i','_',$file)).'" class="'.$cssclass.'" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($file).'&cache='.$cache.'">';
5982
                if ($addlinktofullsize) $ret.='</a>';
5983
            }
5984
            else if ($altfile && file_exists($dir."/".$altfile))
5985
            {
5986
                if ($addlinktofullsize)
5987
                {
5988
                    $urladvanced=getAdvancedPreviewUrl($modulepart, $originalfile);
5989
                    if ($urladvanced) $ret.='<a href="'.$urladvanced.'">';
5990
                    else $ret.='<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($originalfile).'&cache='.$cache.'">';
5991
                }
5992
                $ret.='<img alt="Photo alt" id="photologo'.(preg_replace('/[^a-z]/i','_',$file)).'" class="'.$cssclass.'" '.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.$entity.'&file='.urlencode($altfile).'&cache='.$cache.'">';
5993
                if ($addlinktofullsize) $ret.='</a>';
5994
            }
5995
            else
5996
			{
5997
				$nophoto='/public/theme/common/nophoto.png';
5998
				if (in_array($modulepart,array('userphoto','contact')))	// For module that are "physical" users
5999
				{
6000
					$nophoto='/public/theme/common/user_anonymous.png';
6001
					if ($object->gender == 'man') $nophoto='/public/theme/common/user_man.png';
6002
					if ($object->gender == 'woman') $nophoto='/public/theme/common/user_woman.png';
6003
				}
6004
6005
				if (! empty($conf->gravatar->enabled) && $email)
6006
                {
6007
	                /**
6008
	                 * @see https://gravatar.com/site/implement/images/php/
6009
	                 */
6010
                    global $dolibarr_main_url_root;
6011
                    $ret.='<!-- Put link to gravatar -->';
6012
                    $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="Gravatar avatar" title="'.$email.' Gravatar avatar" border="0"'.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="https://www.gravatar.com/avatar/'.dol_hash(strtolower(trim($email)),3).'?s='.$width.'&d='.urlencode(dol_buildpath($nophoto,3)).'">';	// gravatar need md5 hash
6013
                }
6014
                else
6015
				{
6016
				    if ($conf->browser->layout != 'phone')
6017
				    {
6018
                        $ret.='<img class="photo'.$modulepart.($cssclass?' '.$cssclass:'').'" alt="No photo" border="0"'.($width?' width="'.$width.'"':'').($height?' height="'.$height.'"':'').' src="'.DOL_URL_ROOT.$nophoto.'">';
6019
				    }
6020
                }
6021
            }
6022
6023
            if ($caneditfield)
6024
            {
6025
                if ($object->photo) $ret.="<br>\n";
6026
                $ret.='<table class="nobordernopadding centpercent">';
6027
                if ($object->photo) $ret.='<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> '.$langs->trans("Delete").'<br><br></td></tr>';
6028
                //$ret.='<tr><td>'.$langs->trans("PhotoFile").'</td></tr>';
6029
                $ret.='<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"></td></tr>';
6030
                $ret.='</table>';
6031
            }
6032
6033
        }
6034
        else dol_print_error('','Call of showphoto with wrong parameters modulepart='.$modulepart);
6035
6036
        return $ret;
6037
    }
6038
6039
    /**
6040
     *	Return select list of groups
6041
     *
6042
     *  @param	string	$selected       Id group preselected
6043
     *  @param  string	$htmlname       Field name in form
6044
     *  @param  int		$show_empty     0=liste sans valeur nulle, 1=ajoute valeur inconnue
6045
     *  @param  string	$exclude        Array list of groups id to exclude
6046
     * 	@param	int		$disabled		If select list must be disabled
6047
     *  @param  string	$include        Array list of groups id to include
6048
     * 	@param	int		$enableonly		Array list of groups id to be enabled. All other must be disabled
6049
     * 	@param	int		$force_entity	0 or Id of environment to force
6050
     *  @return	string
6051
     *  @see select_dolusers
6052
     */
6053
    function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0)
6054
    {
6055
        global $conf,$user,$langs;
6056
6057
        // Permettre l'exclusion de groupes
6058
        if (is_array($exclude))	$excludeGroups = implode("','",$exclude);
6059
        // Permettre l'inclusion de groupes
6060
        if (is_array($include))	$includeGroups = implode("','",$include);
6061
6062
        $out='';
6063
6064
        // On recherche les groupes
6065
        $sql = "SELECT ug.rowid, ug.nom as name";
6066
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
6067
        {
6068
            $sql.= ", e.label";
6069
        }
6070
        $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as ug ";
6071
        if (! empty($conf->multicompany->enabled) && $conf->entity == 1 && $user->admin && ! $user->entity)
6072
        {
6073
            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entity as e ON e.rowid=ug.entity";
6074
            if ($force_entity) $sql.= " WHERE ug.entity IN (0,".$force_entity.")";
6075
            else $sql.= " WHERE ug.entity IS NOT NULL";
6076
        }
6077
        else
6078
        {
6079
            $sql.= " WHERE ug.entity IN (0,".$conf->entity.")";
6080
        }
6081
        if (is_array($exclude) && $excludeGroups) $sql.= " AND ug.rowid NOT IN ('".$excludeGroups."')";
0 ignored issues
show
Bug introduced by
The variable $excludeGroups 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...
6082
        if (is_array($include) && $includeGroups) $sql.= " AND ug.rowid IN ('".$includeGroups."')";
0 ignored issues
show
Bug introduced by
The variable $includeGroups 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...
6083
        $sql.= " ORDER BY ug.nom ASC";
6084
6085
        dol_syslog(get_class($this)."::select_dolgroups", LOG_DEBUG);
6086
        $resql=$this->db->query($sql);
6087
        if ($resql)
6088
        {
6089
    		// Enhance with select2
6090
	        if ($conf->use_javascript_ajax)
6091
	        {
6092
				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
6093
	           	$comboenhancement = ajax_combobox($htmlname);
6094
                $out.= $comboenhancement;
6095
                $nodatarole=($comboenhancement?' data-role="none"':'');
6096
            }
6097
6098
            $out.= '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').$nodatarole.'>';
0 ignored issues
show
Bug introduced by
The variable $nodatarole 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...
6099
6100
        	$num = $this->db->num_rows($resql);
6101
            $i = 0;
6102
            if ($num)
6103
            {
6104
                if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'>&nbsp;</option>'."\n";
6105
6106
                while ($i < $num)
6107
                {
6108
                    $obj = $this->db->fetch_object($resql);
6109
                    $disableline=0;
6110
                    if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=1;
6111
6112
                    $out.= '<option value="'.$obj->rowid.'"';
6113
                    if ($disableline) $out.= ' disabled';
6114
                    if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid))
6115
                    {
6116
                        $out.= ' selected';
6117
                    }
6118
                    $out.= '>';
6119
6120
                    $out.= $obj->name;
6121
                    if (! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode) && $conf->entity == 1)
6122
                    {
6123
                        $out.= " (".$obj->label.")";
6124
                    }
6125
6126
                    $out.= '</option>';
6127
                    $i++;
6128
                }
6129
            }
6130
            else
6131
            {
6132
                if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'></option>'."\n";
6133
                $out.= '<option value="" disabled>'.$langs->trans("NoUserGroupDefined").'</option>';
6134
            }
6135
            $out.= '</select>';
6136
        }
6137
        else
6138
        {
6139
            dol_print_error($this->db);
6140
        }
6141
6142
        return $out;
6143
    }
6144
6145
    /**
6146
     *	Return HTML to show the search and clear seach button
6147
     *
6148
     *  @param	int  	$addcheckuncheckall        Add the check all/uncheck all checkbox (use javascript) and code to manage this
6149
     *  @param  string  $cssclass                  CSS class
6150
     *  @param  int     $calljsfunction            0=default. 1=call function initCheckForSelect() after changing status of checkboxes
6151
     *  @return	string
6152
     */
6153
    function showFilterAndCheckAddButtons($addcheckuncheckall=0, $cssclass='checkforaction', $calljsfunction=0)
6154
    {
6155
        global $conf, $langs;
6156
6157
        $out='<div class="nowrap">';
6158
        $out.='<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"),'search.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
6159
        $out.='<input type="image" class="liste_titre" name="button_removefilter" src="'.img_picto($langs->trans("Search"),'searchclear.png','','',1).'" value="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">';
6160
        $out.='</div>';
6161
        if ($addcheckuncheckall)
6162
        {
6163
            if (! empty($conf->use_javascript_ajax)) $out.='<input type="checkbox" id="checkallactions" name="checkallactions" class="checkallactions">';
6164
            $out.='<script type="text/javascript">
6165
                $(document).ready(function() {
6166
                	$("#checkallactions").click(function() {
6167
                        if($(this).is(\':checked\')){
6168
                            console.log("We check all");
6169
                    		$(".'.$cssclass.'").prop(\'checked\', true);
6170
                        }
6171
                        else
6172
                        {
6173
                            console.log("We uncheck all");
6174
                    		$(".'.$cssclass.'").prop(\'checked\', false);
6175
                        }'."\n";
6176
            if ($calljsfunction) $out.='if (typeof initCheckForSelect == \'function\') { initCheckForSelect(); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }';
6177
            $out.='         });
6178
                    });
6179
                </script>';
6180
        }
6181
        return $out;
6182
    }
6183
}
6184
6185