Completed
Branch develop (2959dc)
by
unknown
32:39
created

pdf.lib.php ➔ pdf_getInstance()   F

Complexity

Conditions 11
Paths 396

Size

Total Lines 90
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 47
nc 396
nop 3
dl 0
loc 90
rs 3.8181
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2006-2017	Laurent Destailleur 	<[email protected]>
3
 * Copyright (C) 2006		Rodolphe Quiedeville	<[email protected]>
4
 * Copyright (C) 2007		Patrick Raguin      	<[email protected]>
5
 * Copyright (C) 2010-2012	Regis Houssin       	<[email protected]>
6
 * Copyright (C) 2010-2017	Juanjo Menent       	<[email protected]>
7
 * Copyright (C) 2012		Christophe Battarel		<[email protected]>
8
 * Copyright (C) 2012       Cédric Salvador         <[email protected]>
9
 * Copyright (C) 2012-2015  Raphaël Doursenaud      <[email protected]>
10
 * Copyright (C) 2014		Cedric GROSS			<[email protected]>
11
 * Copyright (C) 2014		Teddy Andreotti			<[email protected]>
12
 * Copyright (C) 2015-2016  Marcos García           <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26
 * or see http://www.gnu.org/
27
 */
28
29
/**
30
 *	\file       htdocs/core/lib/pdf.lib.php
31
 *	\brief      Set of functions used for PDF generation
32
 *	\ingroup    core
33
 */
34
35
36
/**
37
 *	Return array with format properties of default PDF format
38
 *
39
 *	@param		Translate	$outputlangs		Output lang to use to autodetect output format if setup not done
40
 *  @return     array							Array('width'=>w,'height'=>h,'unit'=>u);
41
 */
42
function pdf_getFormat(Translate $outputlangs = null)
43
{
44
	global $conf,$db;
45
46
	// Default value if setup was not done and/or entry into c_paper_format not defined
47
	$width=210; $height=297; $unit='mm';
48
49
	if (empty($conf->global->MAIN_PDF_FORMAT))
50
	{
51
		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
52
		$pdfformat=dol_getDefaultFormat($outputlangs);
53
	}
54
	else $pdfformat=$conf->global->MAIN_PDF_FORMAT;
55
56
	$sql="SELECT code, label, width, height, unit FROM ".MAIN_DB_PREFIX."c_paper_format";
57
	$sql.=" WHERE code = '".$pdfformat."'";
58
	$resql=$db->query($sql);
59
	if ($resql)
60
	{
61
		$obj=$db->fetch_object($resql);
62
		if ($obj)
63
		{
64
			$width=(int) $obj->width;
65
			$height=(int) $obj->height;
66
			$unit=$obj->unit;
67
		}
68
	}
69
70
	//print "pdfformat=".$pdfformat." width=".$width." height=".$height." unit=".$unit;
71
	return array('width'=>$width,'height'=>$height,'unit'=>$unit);
72
}
73
74
/**
75
 *      Return a PDF instance object. We create a FPDI instance that instantiate TCPDF.
76
 *
77
 *      @param	string		$format         Array(width,height). Keep empty to use default setup.
78
 *      @param	string		$metric         Unit of format ('mm')
79
 *      @param  string		$pagetype       'P' or 'l'
80
 *      @return TCPDF						PDF object
81
 */
82
function pdf_getInstance($format='',$metric='mm',$pagetype='P')
83
{
84
	global $conf;
85
86
	// Define constant for TCPDF
87
	if (! defined('K_TCPDF_EXTERNAL_CONFIG'))
88
	{
89
		define('K_TCPDF_EXTERNAL_CONFIG',1);	// this avoid using tcpdf_config file
90
		define('K_PATH_CACHE', DOL_DATA_ROOT.'/admin/temp/');
91
		define('K_PATH_URL_CACHE', DOL_DATA_ROOT.'/admin/temp/');
92
		dol_mkdir(K_PATH_CACHE);
93
		define('K_BLANK_IMAGE', '_blank.png');
94
		define('PDF_PAGE_FORMAT', 'A4');
95
		define('PDF_PAGE_ORIENTATION', 'P');
96
		define('PDF_CREATOR', 'TCPDF');
97
		define('PDF_AUTHOR', 'TCPDF');
98
		define('PDF_HEADER_TITLE', 'TCPDF Example');
99
		define('PDF_HEADER_STRING', "by Dolibarr ERP CRM");
100
		define('PDF_UNIT', 'mm');
101
		define('PDF_MARGIN_HEADER', 5);
102
		define('PDF_MARGIN_FOOTER', 10);
103
		define('PDF_MARGIN_TOP', 27);
104
		define('PDF_MARGIN_BOTTOM', 25);
105
		define('PDF_MARGIN_LEFT', 15);
106
		define('PDF_MARGIN_RIGHT', 15);
107
		define('PDF_FONT_NAME_MAIN', 'helvetica');
108
		define('PDF_FONT_SIZE_MAIN', 10);
109
		define('PDF_FONT_NAME_DATA', 'helvetica');
110
		define('PDF_FONT_SIZE_DATA', 8);
111
		define('PDF_FONT_MONOSPACED', 'courier');
112
		define('PDF_IMAGE_SCALE_RATIO', 1.25);
113
		define('HEAD_MAGNIFICATION', 1.1);
114
		define('K_CELL_HEIGHT_RATIO', 1.25);
115
		define('K_TITLE_MAGNIFICATION', 1.3);
116
		define('K_SMALL_RATIO', 2/3);
117
		define('K_THAI_TOPCHARS', true);
118
		define('K_TCPDF_CALLS_IN_HTML', true);
119
		define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
120
	}
121
122
	// Load TCPDF
123
	require_once TCPDF_PATH.'tcpdf.php';
124
125
	// We need to instantiate tcpdi object (instead of tcpdf) to use merging features. But we can disable it (this will break all merge features).
126
	if (empty($conf->global->MAIN_DISABLE_TCPDI)) require_once TCPDI_PATH.'tcpdi.php';
127
	else if (empty($conf->global->MAIN_DISABLE_FPDI)) require_once FPDI_PATH.'fpdi.php';
128
129
	//$arrayformat=pdf_getFormat();
130
	//$format=array($arrayformat['width'],$arrayformat['height']);
131
	//$metric=$arrayformat['unit'];
132
133
	if (class_exists('TCPDI')) $pdf = new TCPDI($pagetype,$metric,$format);
134
	else $pdf = new TCPDF($pagetype,$metric,$format);
135
136
	// Protection and encryption of pdf
137
	if (! empty($conf->global->PDF_SECURITY_ENCRYPTION))
138
	{
139
		/* Permission supported by TCPDF
140
		- print : Print the document;
141
		- modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';
142
		- copy : Copy or otherwise extract text and graphics from the document;
143
		- annot-forms : Add or modify text annotations, fill in interactive form fields, and, if 'modify' is also set, create or modify interactive form fields (including signature fields);
144
		- fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;
145
		- extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);
146
		- assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;
147
		- print-high : Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set, printing is limited to a low-level representation of the appearance, possibly of degraded quality.
148
		- owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.
149
		*/
150
151
		// For TCPDF, we specify permission we want to block
152
		$pdfrights = (! empty($conf->global->PDF_SECURITY_ENCRYPTION_RIGHTS)?json_decode($conf->global->PDF_SECURITY_ENCRYPTION_RIGHTS, true):array('modify','copy')); // Json format in llx_const
153
154
		// Password for the end user
155
		$pdfuserpass = (! empty($conf->global->PDF_SECURITY_ENCRYPTION_USERPASS)?$conf->global->PDF_SECURITY_ENCRYPTION_USERPASS:'');
156
157
		// Password of the owner, created randomly if not defined
158
		$pdfownerpass = (! empty($conf->global->PDF_SECURITY_ENCRYPTION_OWNERPASS)?$conf->global->PDF_SECURITY_ENCRYPTION_OWNERPASS:null);
159
160
		// For encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit
161
		$encstrength = (! empty($conf->global->PDF_SECURITY_ENCRYPTION_STRENGTH)?$conf->global->PDF_SECURITY_ENCRYPTION_STRENGTH:0);
162
163
		// Array of recipients containing public-key certificates ('c') and permissions ('p').
164
		// For example: array(array('c' => 'file://../examples/data/cert/tcpdf.crt', 'p' => array('print')))
165
		$pubkeys = (! empty($conf->global->PDF_SECURITY_ENCRYPTION_PUBKEYS)?json_decode($conf->global->PDF_SECURITY_ENCRYPTION_PUBKEYS, true):null); // Json format in llx_const
166
167
		$pdf->SetProtection($pdfrights,$pdfuserpass,$pdfownerpass,$encstrength,$pubkeys);
168
	}
169
170
	return $pdf;
171
}
172
173
174
/**
175
 *      Return font name to use for PDF generation
176
 *
177
 *      @param	Translate	$outputlangs    Output langs object
178
 *      @return string          			Name of font to use
179
 */
180
function pdf_getPDFFont($outputlangs)
181
{
182
	global $conf;
183
184
	if (! empty($conf->global->MAIN_PDF_FORCE_FONT)) return $conf->global->MAIN_PDF_FORCE_FONT;
185
186
	$font='Helvetica'; // By default, for FPDI, or ISO language on TCPDF
187
	if (class_exists('TCPDF'))  // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
188
	{
189
		if ($outputlangs->trans('FONTFORPDF')!='FONTFORPDF')
190
		{
191
			$font=$outputlangs->trans('FONTFORPDF');
192
		}
193
	}
194
	return $font;
195
}
196
197
/**
198
 *      Return font size to use for PDF generation
199
 *
200
 *      @param	Translate	$outputlangs     Output langs object
201
 *      @return int				             Size of font to use
202
 */
203
function pdf_getPDFFontSize($outputlangs)
204
{
205
	$size=10;                   // By default, for FPDI or ISO language on TCPDF
206
	if (class_exists('TCPDF'))  // If TCPDF on, we can use an UTF8 one like DejaVuSans if required (slower)
207
	{
208
		if ($outputlangs->trans('FONTSIZEFORPDF')!='FONTSIZEFORPDF')
209
		{
210
			$size = (int) $outputlangs->trans('FONTSIZEFORPDF');
211
		}
212
	}
213
	return $size;
214
}
215
216
217
/**
218
 * Return height to use for Logo onto PDF
219
 *
220
 * @param	string		$logo		Full path to logo file to use
221
 * @param	bool		$url		Image with url (true or false)
222
 * @return	number
223
 */
224
function pdf_getHeightForLogo($logo, $url = false)
225
{
226
	global $conf;
227
	$height=(empty($conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT)?22:$conf->global->MAIN_DOCUMENTS_LOGO_HEIGHT);
228
	$maxwidth=130;
229
	include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
230
	$tmp=dol_getImageSize($logo, $url);
231
	if ($tmp['height'])
232
	{
233
		$width=round($height*$tmp['width']/$tmp['height']);
234
		if ($width > $maxwidth) $height=$height*$maxwidth/$width;
235
	}
236
	//print $tmp['width'].' '.$tmp['height'].' '.$width; exit;
237
	return $height;
238
}
239
240
/**
241
 * Function to try to calculate height of a HTML Content
242
 *
243
 * @param TCPDF     $pdf            PDF initialized object
244
 * @param string    $htmlcontent    HTML Contect
245
 * @see getStringHeight
246
 */
247
function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
248
{
249
    // store current object
250
    $pdf->startTransaction();
251
    // store starting values
252
    $start_y = $pdf->GetY();
253
    //var_dump($start_y);
254
    $start_page = $pdf->getPage();
255
    // call printing functions with content
256
    $pdf->writeHTMLCell(0, 0, 0, $start_y, $htmlcontent, 0, 1, false, true, 'J',true);
257
    // get the new Y
258
    $end_y = $pdf->GetY();
259
    $end_page = $pdf->getPage();
260
    // calculate height
261
    $height = 0;
262
    if ($end_page == $start_page) {
263
        $height = $end_y - $start_y;
264
    }
265
    else
266
    {
267
        for ($page=$start_page; $page <= $end_page; ++$page) {
268
        	$pdf->setPage($page);
269
        	$tmpm=$pdf->getMargins();
270
        	$tMargin = $tmpm['top'];
271
        	if ($page == $start_page) {
272
        		// first page
273
        		$height = $pdf->getPageHeight() - $start_y - $pdf->getBreakMargin();
274
        	} elseif ($page == $end_page) {
275
        		// last page
276
        		$height = $end_y - $tMargin;
277
        	} else {
278
        		$height = $pdf->getPageHeight() - $tMargin - $pdf->getBreakMargin();
279
        	}
280
        }
281
	}
282
	// restore previous object
283
	$pdf = $pdf->rollbackTransaction();
284
285
    return $height;
286
}
287
288
289
/**
290
 * Returns the name of the thirdparty
291
 *
292
 * @param   Societe|Contact     $thirdparty     Contact or thirdparty
293
 * @param   Translate           $outputlangs    Output language
294
 * @param   int                 $includealias   1=Include alias name after name
295
 * @return  string                              String with name of thirdparty (+ alias if requested)
296
 */
297
function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includealias=0)
298
{
299
    global $conf;
300
301
	// Recipient name
302
	$socname = '';
303
304
	if ($thirdparty instanceof Societe) {
305
		$socname .= $thirdparty->name;
306
		if (($includealias || ! empty($conf->global->PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME)) && !empty($thirdparty->name_alias)) {
307
		    $socname .= "\n".$thirdparty->name_alias;
308
		}
309
	} elseif ($thirdparty instanceof Contact) {
310
		$socname = $thirdparty->socname;
311
	} else {
312
		throw new InvalidArgumentException('Parameter 1 $thirdparty is not a Societe nor Contact');
313
	}
314
315
	return $outputlangs->convToOutputCharset($socname);
316
}
317
318
319
/**
320
 *   	Return a string with full address formated for output on documents
321
 *
322
 * 		@param	Translate	$outputlangs		Output langs object
323
 *   	@param  Societe		$sourcecompany		Source company object
324
 *   	@param  Societe		$targetcompany		Target company object
325
 *      @param  Contact		$targetcontact		Target contact object
326
 * 		@param	int			$usecontact			Use contact instead of company
327
 * 		@param	int			$mode				Address type ('source', 'target', 'targetwithdetails', 'targetwithdetails_xxx': target but include also phone/fax/email/url)
328
 *      @param  Object      $object             Object we want to build document for
329
 * 		@return	string							String with full address
330
 */
331
function pdf_build_address($outputlangs,$sourcecompany,$targetcompany='',$targetcontact='',$usecontact=0,$mode='source',$object=null)
332
{
333
	global $conf, $hookmanager;
334
335
	if ($mode == 'source' && ! is_object($sourcecompany)) return -1;
336
	if ($mode == 'target' && ! is_object($targetcompany)) return -1;
337
338
	if (! empty($sourcecompany->state_id) && empty($sourcecompany->departement)) $sourcecompany->departement=getState($sourcecompany->state_id); //TODO deprecated
339
	if (! empty($sourcecompany->state_id) && empty($sourcecompany->state))       $sourcecompany->state=getState($sourcecompany->state_id);
340
	if (! empty($sourcecompany->state_id) && !isset($sourcecompany->departement_id))   $sourcecompany->departement_id=getState($sourcecompany->state_id,'2');
341
	if (! empty($targetcompany->state_id) && empty($targetcompany->departement)) $targetcompany->departement=getState($targetcompany->state_id); //TODO deprecated
342
	if (! empty($targetcompany->state_id) && empty($targetcompany->state))       $targetcompany->state=getState($targetcompany->state_id);
343
	if (! empty($targetcompany->state_id) && !isset($targetcompany->departement_id))   $targetcompany->departement_id=getState($targetcompany->state_id,'2');
344
345
	$reshook=0;
346
	$stringaddress = '';
347
	if (is_object($hookmanager))
348
	{
349
		$parameters = array('sourcecompany'=>&$sourcecompany,'targetcompany'=>&$targetcompany,'targetcontact'=>$targetcontact,'outputlangs'=>$outputlangs,'mode'=>$mode,'usecontact'=>$usecontact);
350
		$action='';
351
		$reshook = $hookmanager->executeHooks('pdf_build_address',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
352
		$stringaddress.=$hookmanager->resPrint;
353
	}
354
	if (empty($reshook))
355
	{
356
    	if ($mode == 'source')
357
    	{
358
    		$withCountry = 0;
359
    		if (!empty($sourcecompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) $withCountry = 1;
360
361
    		$stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs))."\n";
362
363
    		if (empty($conf->global->MAIN_PDF_DISABLESOURCEDETAILS))
364
    		{
365
    			// Phone
366
    			if ($sourcecompany->phone) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
367
    			// Fax
368
    			if ($sourcecompany->fax) $stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '' ).$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
369
    			// EMail
370
    			if ($sourcecompany->email) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($sourcecompany->email);
371
    			// Web
372
    			if ($sourcecompany->url) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($sourcecompany->url);
373
    		}
374
    	}
375
376
    	if ($mode == 'target' || preg_match('/targetwithdetails/',$mode))
377
    	{
378
    		if ($usecontact)
379
    		{
380
    			$stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset($targetcontact->getFullName($outputlangs,1));
0 ignored issues
show
Bug introduced by
It seems like $targetcontact 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...
381
382
    			if (!empty($targetcontact->address)) {
383
    				$stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($targetcontact));
0 ignored issues
show
Bug introduced by
It seems like $targetcontact defined by parameter $targetcontact on line 331 can also be of type string; however, dol_format_address() does only seem to accept object, 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...
384
    			}else {
385
    				$stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
0 ignored issues
show
Bug introduced by
It seems like $targetcompany defined by parameter $targetcompany on line 331 can also be of type string; however, dol_format_address() does only seem to accept object, 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...
386
    			}
387
    			// Country
388
    			if (!empty($targetcontact->country_code) && $targetcontact->country_code != $sourcecompany->country_code) {
389
    				$stringaddress.= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcontact->country_code));
390
    			}
391
    			else if (empty($targetcontact->country_code) && !empty($targetcompany->country_code) && ($targetcompany->country_code != $sourcecompany->country_code)) {
392
    				$stringaddress.= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
393
    			}
394
395
    			if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || preg_match('/targetwithdetails/',$mode))
396
    			{
397
    				// Phone
398
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/',$mode))
399
    			    {
400
        				if (! empty($targetcontact->phone_pro) || ! empty($targetcontact->phone_mobile)) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Phone").": ";
401
        				if (! empty($targetcontact->phone_pro)) $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_pro);
402
        				if (! empty($targetcontact->phone_pro) && ! empty($targetcontact->phone_mobile)) $stringaddress .= " / ";
403
        				if (! empty($targetcontact->phone_mobile)) $stringaddress .= $outputlangs->convToOutputCharset($targetcontact->phone_mobile);
404
    			    }
405
    				// Fax
406
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/',$mode))
407
    			    {
408
                        if ($targetcontact->fax) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcontact->fax);
409
    			    }
410
    				// EMail
411
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/',$mode))
412
    			    {
413
                        if ($targetcontact->email) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcontact->email);
414
    			    }
415
    				// Web
416
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/',$mode))
417
    			    {
418
                        if ($targetcontact->url) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcontact->url);
419
    			    }
420
    			}
421
    		}
422
    		else
423
    		{
424
    			$stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset(dol_format_address($targetcompany));
0 ignored issues
show
Bug introduced by
It seems like $targetcompany defined by parameter $targetcompany on line 331 can also be of type string; however, dol_format_address() does only seem to accept object, 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...
425
    			// Country
426
    			if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) $stringaddress.=($stringaddress ? "\n" : '' ).$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code));
427
428
    			if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || preg_match('/targetwithdetails/',$mode))
429
    			{
430
    				// Phone
431
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_phone/',$mode))
432
    			    {
433
    			    	if (! empty($targetcompany->phone) || ! empty($targetcompany->phone_mobile)) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Phone").": ";
434
	    				if (! empty($targetcompany->phone)) $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone);
435
    					if (! empty($targetcompany->phone) && ! empty($targetcompany->phone_mobile)) $stringaddress .= " / ";
436
    					if (! empty($targetcompany->phone_mobile)) $stringaddress .= $outputlangs->convToOutputCharset($targetcompany->phone_mobile);
437
    			    }
438
    				// Fax
439
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_fax/',$mode))
440
    			    {
441
    			    	if ($targetcompany->fax) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($targetcompany->fax);
442
    			    }
443
    				// EMail
444
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_email/',$mode))
445
    			    {
446
    			    	if ($targetcompany->email) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Email").": ".$outputlangs->convToOutputCharset($targetcompany->email);
447
    			    }
448
    				// Web
449
    			    if (! empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || $mode == 'targetwithdetails' || preg_match('/targetwithdetails_url/',$mode))
450
    			    {
451
    			    	if ($targetcompany->url) $stringaddress .= ($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("Web").": ".$outputlangs->convToOutputCharset($targetcompany->url);
452
    			    }
453
    			}
454
    		}
455
456
    		// Intra VAT
457
    		if (empty($conf->global->MAIN_TVAINTRA_NOT_IN_ADDRESS))
458
    		{
459
    			if ($targetcompany->tva_intra) $stringaddress.=($stringaddress ? "\n" : '' ).$outputlangs->transnoentities("VATIntraShort").': '.$outputlangs->convToOutputCharset($targetcompany->tva_intra);
460
    		}
461
462
    		// Professionnal Ids
463
    		if (! empty($conf->global->MAIN_PROFID1_IN_ADDRESS) && ! empty($targetcompany->idprof1))
464
    		{
465
    			$tmp=$outputlangs->transcountrynoentities("ProfId1",$targetcompany->country_code);
466
    			if (preg_match('/\((.+)\)/',$tmp,$reg)) $tmp=$reg[1];
467
    			$stringaddress.=($stringaddress ? "\n" : '' ).$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof1);
468
    		}
469
    		if (! empty($conf->global->MAIN_PROFID2_IN_ADDRESS) && ! empty($targetcompany->idprof2))
470
    		{
471
    			$tmp=$outputlangs->transcountrynoentities("ProfId2",$targetcompany->country_code);
472
    			if (preg_match('/\((.+)\)/',$tmp,$reg)) $tmp=$reg[1];
473
    			$stringaddress.=($stringaddress ? "\n" : '' ).$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof2);
474
    		}
475
    		if (! empty($conf->global->MAIN_PROFID3_IN_ADDRESS) && ! empty($targetcompany->idprof3))
476
    		{
477
    			$tmp=$outputlangs->transcountrynoentities("ProfId3",$targetcompany->country_code);
478
    			if (preg_match('/\((.+)\)/',$tmp,$reg)) $tmp=$reg[1];
479
    			$stringaddress.=($stringaddress ? "\n" : '' ).$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof3);
480
    		}
481
    		if (! empty($conf->global->MAIN_PROFID4_IN_ADDRESS) && ! empty($targetcompany->idprof4))
482
    		{
483
    			$tmp=$outputlangs->transcountrynoentities("ProfId4",$targetcompany->country_code);
484
    			if (preg_match('/\((.+)\)/',$tmp,$reg)) $tmp=$reg[1];
485
    			$stringaddress.=($stringaddress ? "\n" : '' ).$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof4);
486
    		}
487
    		if (! empty($conf->global->MAIN_PROFID5_IN_ADDRESS) && ! empty($targetcompany->idprof5))
488
    		{
489
    		    $tmp=$outputlangs->transcountrynoentities("ProfId5",$targetcompany->country_code);
490
    		    if (preg_match('/\((.+)\)/',$tmp,$reg)) $tmp=$reg[1];
491
    		    $stringaddress.=($stringaddress ? "\n" : '' ).$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof5);
492
    		}
493
    		if (! empty($conf->global->MAIN_PROFID6_IN_ADDRESS) && ! empty($targetcompany->idprof6))
494
    		{
495
    		    $tmp=$outputlangs->transcountrynoentities("ProfId6",$targetcompany->country_code);
496
    		    if (preg_match('/\((.+)\)/',$tmp,$reg)) $tmp=$reg[1];
497
    		    $stringaddress.=($stringaddress ? "\n" : '' ).$tmp.': '.$outputlangs->convToOutputCharset($targetcompany->idprof6);
498
    		}
499
500
    		// Public note
501
    		if (! empty($conf->global->MAIN_PUBLIC_NOTE_IN_ADDRESS))
502
    		{
503
    		    if ($mode == 'source' && ! empty($sourcecompany->note_public))
504
        		{
505
        		    $stringaddress.=($stringaddress ? "\n" : '' ).dol_string_nohtmltag($sourcecompany->note_public);
506
        		}
507
        		if (($mode == 'target' || preg_match('/targetwithdetails/',$mode)) && ! empty($targetcompany->note_public))
508
        		{
509
        		    $stringaddress.=($stringaddress ? "\n" : '' ).dol_string_nohtmltag($targetcompany->note_public);
510
        		}
511
    		}
512
    	}
513
	}
514
515
	return $stringaddress;
516
}
517
518
519
/**
520
 *   	Show header of page for PDF generation
521
 *
522
 *   	@param      TCPDF			$pdf     		Object PDF
523
 *      @param      Translate	$outputlangs	Object lang for output
524
 * 		@param		int			$page_height	Height of page
525
 *      @return	void
526
 */
527
function pdf_pagehead(&$pdf,$outputlangs,$page_height)
528
{
529
	global $conf;
530
531
	// Add a background image on document
532
	if (! empty($conf->global->MAIN_USE_BACKGROUND_ON_PDF))		// Warning, this option make TCPDF generation being crazy and some content disappeared behind the image
533
	{
534
		$pdf->SetAutoPageBreak(0,0);	// Disable auto pagebreak before adding image
535
		$pdf->Image($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_USE_BACKGROUND_ON_PDF, (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_X)?$conf->global->MAIN_USE_BACKGROUND_ON_PDF_X:0), (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y)?$conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y:0), 0, $page_height);
536
		$pdf->SetAutoPageBreak(1,0);	// Restore pagebreak
537
	}
538
}
539
540
541
/**
542
 *	Return array of possible substitutions for PDF content (without external module substitutions).
543
 *
544
 *	@param	Translate	$outputlangs	Output language
545
 *	@param	array       $exclude        Array of family keys we want to exclude. For example array('mycompany', 'object', 'date', 'user', ...)
546
 *	@param	Object      $object         Object
547
 *	@param	int         $onlykey       1=Do not calculate some heavy values of keys (performance enhancement when we need only the keys), 2=Values are truncated and html sanitized (to use for help tooltip)
548
 *	@return	array						Array of substitutions
549
 */
550
function pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null, $onlykey=0)
551
{
552
    $substitutionarray = getCommonSubstitutionArray($outputlangs, $onlykey, $exclude, $object);
553
    $substitutionarray['__FROM_NAME__']='__FROM_NAME__';
554
    $substitutionarray['__FROM_EMAIL__']='__FROM_EMAIL__';
555
    return $substitutionarray;
556
}
557
558
559
/**
560
 *      Add a draft watermark on PDF files
561
 *
562
 *      @param	TCPDF      	$pdf            Object PDF
563
 *      @param  Translate	$outputlangs	Object lang
564
 *      @param  int		    $h		        Height of PDF
565
 *      @param  int		    $w		        Width of PDF
566
 *      @param  string	    $unit           Unit of height (mm, pt, ...)
567
 *      @param  string		$text           Text to show
568
 *      @return	void
569
 */
570
function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text)
571
{
572
	global $langs, $mysoc, $user;
573
574
	// Print Draft Watermark
575
	if ($unit=='pt') $k=1;
576
	elseif ($unit=='mm') $k=72/25.4;
577
	elseif ($unit=='cm') $k=72/2.54;
578
	elseif ($unit=='in') $k=72;
579
580
	// Make substitution
581
	$substitutionarray=pdf_getSubstitutionArray($outputlangs, null, null);
582
	complete_substitutions_array($substitutionarray, $outputlangs, null);
583
	$text=make_substitutions($text, $substitutionarray, $outputlangs);
584
	$text=$outputlangs->convToOutputCharset($text);
585
586
	$savx=$pdf->getX(); $savy=$pdf->getY();
587
588
	$watermark_angle=atan($h/$w)/2;
589
	$watermark_x_pos=0;
590
	$watermark_y_pos=$h/3;
591
	$watermark_x=$w/2;
592
	$watermark_y=$h/3;
593
	$pdf->SetFont('','B',40);
594
	$pdf->SetTextColor(255,192,203);
595
	//rotate
596
	$pdf->_out(sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm',cos($watermark_angle),sin($watermark_angle),-sin($watermark_angle),cos($watermark_angle),$watermark_x*$k,($h-$watermark_y)*$k,-$watermark_x*$k,-($h-$watermark_y)*$k));
0 ignored issues
show
Bug introduced by
The variable $k 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...
597
	//print watermark
598
	$pdf->SetXY($watermark_x_pos,$watermark_y_pos);
599
	$pdf->Cell($w-20,25,$outputlangs->convToOutputCharset($text),"",2,"C",0);
600
	//antirotate
601
	$pdf->_out('Q');
602
603
	$pdf->SetXY($savx,$savy);
604
}
605
606
607
/**
608
 *  Show bank informations for PDF generation
609
 *
610
 *  @param	TCPDF			$pdf            		Object PDF
611
 *  @param  Translate	$outputlangs     		Object lang
612
 *  @param  int			$curx            		X
613
 *  @param  int			$cury            		Y
614
 *  @param  Account		$account         		Bank account object
615
 *  @param  int			$onlynumber      		Output only number (bank+desk+key+number according to country, but without name of bank and domiciliation)
616
 *  @param	int			$default_font_size		Default font size
617
 *  @return	float                               The Y PDF position
618
 */
619
function pdf_bank(&$pdf,$outputlangs,$curx,$cury,$account,$onlynumber=0,$default_font_size=10)
620
{
621
	global $mysoc, $conf;
622
623
	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php';
624
625
	$diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
626
	$diffsizecontent=(empty($conf->global->PDF_DIFFSIZE_CONTENT)?4:$conf->global->PDF_DIFFSIZE_CONTENT);
627
	$pdf->SetXY($curx, $cury);
628
629
	if (empty($onlynumber))
630
	{
631
		$pdf->SetFont('','B',$default_font_size - $diffsizetitle);
632
		$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByTransferOnThisBankAccount').':', 0, 'L', 0);
633
		$cury+=4;
634
	}
635
636
	$outputlangs->load("banks");
637
638
	// Use correct name of bank id according to country
639
	$bickey="BICNumber";
640
	if ($account->getCountryCode() == 'IN') $bickey="SWIFT";
641
642
	// Get format of bank account according to its country
643
	$usedetailedbban=$account->useDetailedBBAN();
644
645
	//$onlynumber=0; $usedetailedbban=1; // For tests
646
	if ($usedetailedbban)
647
	{
648
		$savcurx=$curx;
649
650
		if (empty($onlynumber))
651
		{
652
			$pdf->SetFont('','',$default_font_size - $diffsizecontent);
653
			$pdf->SetXY($curx, $cury);
654
			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': ' . $outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
655
			$cury+=3;
656
		}
657
658
		if (empty($conf->global->PDF_BANK_HIDE_NUMBER_SHOW_ONLY_BICIBAN))    // Note that some countries still need bank number, BIC/IBAN not enought for them
659
		{
660
		    // Note:
661
		    // bank = code_banque (FR), sort code (GB, IR. Example: 12-34-56)
662
		    // desk = code guichet (FR), used only when $usedetailedbban = 1
663
		    // number = account number
664
		    // key = check control key used only when $usedetailedbban = 1
665
    		if (empty($onlynumber)) $pdf->line($curx+1, $cury+1, $curx+1, $cury+6);
666
667
668
			foreach ($account->getFieldsToShow() as $val)
669
			{
670
				$pdf->SetXY($curx, $cury+4);
671
				$pdf->SetFont('','',$default_font_size - 3);
672
673
				if ($val == 'BankCode') {
674
					// Bank code
675
					$tmplength = 18;
676
					$content = $account->code_banque;
677
				} elseif ($val == 'DeskCode') {
678
					// Desk
679
					$tmplength = 18;
680
					$content = $account->code_guichet;
681
				} elseif ($val == 'BankAccountNumber') {
682
					// Number
683
					$tmplength = 24;
684
					$content = $account->number;
685
				} elseif ($val == 'BankAccountNumberKey') {
686
					// Key
687
					$tmplength = 13;
688
					$content = $account->cle_rib;
689
				}elseif ($val == 'IBAN' || $val == 'BIC') {
690
					// Key
691
					$tmplength = 0;
692
					$content = '';
693
				} else {
694
					dol_print_error($account->db, 'Unexpected value for getFieldsToShow: '.$val);
695
					break;
696
				}
697
698
				$pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0);
699
				$pdf->SetXY($curx, $cury + 1);
700
				$curx += $tmplength;
701
				$pdf->SetFont('', 'B', $default_font_size - $diffsizecontent);
702
				$pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0);
703
				if (empty($onlynumber)) {
704
					$pdf->line($curx, $cury + 1, $curx, $cury + 7);
705
				}
706
    		}
707
708
    		$curx=$savcurx;
709
    		$cury+=8;
710
		}
711
	}
712
	else
713
	{
714
		$pdf->SetFont('','B',$default_font_size - $diffsizecontent);
715
		$pdf->SetXY($curx, $cury);
716
		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("Bank").': ' . $outputlangs->convToOutputCharset($account->bank), 0, 'L', 0);
717
		$cury+=3;
718
719
		$pdf->SetFont('','B',$default_font_size - $diffsizecontent);
720
		$pdf->SetXY($curx, $cury);
721
		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("BankAccountNumber").': ' . $outputlangs->convToOutputCharset($account->number), 0, 'L', 0);
722
		$cury+=3;
723
724
		if ($diffsizecontent <= 2) $cury+=1;
725
	}
726
727
	$pdf->SetFont('','',$default_font_size - $diffsizecontent);
728
729
	if (empty($onlynumber) && ! empty($account->domiciliation))
730
	{
731
		$pdf->SetXY($curx, $cury);
732
		$val=$outputlangs->transnoentities("Residence").': ' . $outputlangs->convToOutputCharset($account->domiciliation);
733
		$pdf->MultiCell(100, 3, $val, 0, 'L', 0);
734
		//$nboflines=dol_nboflines_bis($val,120);
735
		//$cury+=($nboflines*3)+2;
736
		$tmpy=$pdf->getStringHeight(100, $val);
737
		$cury+=$tmpy;
738
	}
739
740
	if (! empty($account->proprio))
741
	{
742
		$pdf->SetXY($curx, $cury);
743
		$val=$outputlangs->transnoentities("BankAccountOwner").': ' . $outputlangs->convToOutputCharset($account->proprio);
744
		$pdf->MultiCell(100, 3, $val, 0, 'L', 0);
745
		$tmpy=$pdf->getStringHeight(100, $val);
746
		$cury+=$tmpy;
747
		$cur+=1;
0 ignored issues
show
Bug introduced by
The variable $cur 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...
748
	}
749
750
	else if (! $usedetailedbban) $cury+=1;
751
752
	// Use correct name of bank id according to country
753
	$ibankey = FormBank::getIBANLabel($account);
754
755
	if (! empty($account->iban))
756
	{
757
		//Remove whitespaces to ensure we are dealing with the format we expect
758
		$ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban));
759
		$ibanDisplay = "";
760
761
		$nbIbanDisplay_temp = dol_strlen($ibanDisplay_temp);
762
		for ($i = 0; $i < $nbIbanDisplay_temp; $i++)
763
		{
764
			$ibanDisplay .= $ibanDisplay_temp[$i];
765
			if($i%4 == 3 && $i > 0)	$ibanDisplay .= " ";
766
		}
767
768
		$pdf->SetFont('','B',$default_font_size - 3);
769
		$pdf->SetXY($curx, $cury);
770
		$pdf->MultiCell(100, 3, $outputlangs->transnoentities($ibankey).': ' . $ibanDisplay, 0, 'L', 0);
771
		$cury+=3;
772
	}
773
774
	if (! empty($account->bic))
775
	{
776
		$pdf->SetFont('','B',$default_font_size - 3);
777
		$pdf->SetXY($curx, $cury);
778
		$pdf->MultiCell(100, 3, $outputlangs->transnoentities($bickey).': ' . $outputlangs->convToOutputCharset($account->bic), 0, 'L', 0);
779
	}
780
781
	return $pdf->getY();
782
}
783
784
/**
785
 *  Show footer of page for PDF generation
786
 *
787
 *	@param	TCPDF			$pdf     		The PDF factory
788
 *  @param  Translate	$outputlangs	Object lang for output
789
 * 	@param	string		$paramfreetext	Constant name of free text
790
 * 	@param	Societe		$fromcompany	Object company
791
 * 	@param	int			$marge_basse	Margin bottom we use for the autobreak
792
 * 	@param	int			$marge_gauche	Margin left (no more used)
793
 * 	@param	int			$page_hauteur	Page height (no more used)
794
 * 	@param	Object		$object			Object shown in PDF
795
 * 	@param	int			$showdetails	Show company adress details into footer (0=Nothing, 1=Show address, 2=Show managers, 3=Both)
796
 *  @param	int			$hidefreetext	1=Hide free text, 0=Show free text
797
 * 	@return	int							Return height of bottom margin including footer text
798
 */
799
function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_basse,$marge_gauche,$page_hauteur,$object,$showdetails=0,$hidefreetext=0)
800
{
801
	global $conf,$user,$mysoc;
802
803
	$outputlangs->load("dict");
804
	$line='';
805
806
	$dims=$pdf->getPageDimensions();
807
808
	// Line of free text
809
	if (empty($hidefreetext) && ! empty($conf->global->$paramfreetext))
810
	{
811
		$substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
812
		// More substitution keys
813
		$substitutionarray['__FROM_NAME__']=$fromcompany->name;
814
		$substitutionarray['__FROM_EMAIL__']=$fromcompany->email;
815
		complete_substitutions_array($substitutionarray, $outputlangs, $object);
816
		$newfreetext=make_substitutions($conf->global->$paramfreetext, $substitutionarray, $outputlangs);
817
818
		// Make a change into HTML code to allow to include images from medias directory.
819
		// <img alt="" src="/dolibarr_dev/htdocs/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
820
		// become
821
		// <img alt="" src="'.DOL_DATA_ROOT.'/medias/image/ldestailleur_166x166.jpg" style="height:166px; width:166px" />
822
		$newfreetext=preg_replace('/(<img.*src=")[^\"]*viewimage\.php[^\"]*modulepart=medias[^\"]*file=([^\"]*)("[^\/]*\/>)/', '\1'.DOL_DATA_ROOT.'/medias/\2\3', $newfreetext);
823
824
		$line.=$outputlangs->convToOutputCharset($newfreetext);
825
	}
826
827
	// First line of company infos
828
	$line1=""; $line2=""; $line3=""; $line4="";
829
830
		if ($showdetails == 1 || $showdetails == 3)
831
	{
832
		// Company name
833
		if ($fromcompany->name)
834
		{
835
			$line1.=($line1?" - ":"").$outputlangs->transnoentities("RegisteredOffice").": ".$fromcompany->name;
836
		}
837
		// Address
838
		if ($fromcompany->address)
839
		{
840
			$line1.=($line1?" - ":"").str_replace("\n", ", ", $fromcompany->address);
841
		}
842
		// Zip code
843
		if ($fromcompany->zip)
844
		{
845
			$line1.=($line1?" - ":"").$fromcompany->zip;
846
		}
847
		// Town
848
		if ($fromcompany->town)
849
		{
850
			$line1.=($line1?" ":"").$fromcompany->town;
851
		}
852
		// Phone
853
		if ($fromcompany->phone)
854
		{
855
			$line2.=($line2?" - ":"").$outputlangs->transnoentities("Phone").": ".$fromcompany->phone;
856
		}
857
		// Fax
858
		if ($fromcompany->fax)
859
		{
860
			$line2.=($line2?" - ":"").$outputlangs->transnoentities("Fax").": ".$fromcompany->fax;
861
		}
862
863
		// URL
864
		if ($fromcompany->url)
865
		{
866
			$line2.=($line2?" - ":"").$fromcompany->url;
867
		}
868
		// Email
869
		if ($fromcompany->email)
870
		{
871
			$line2.=($line2?" - ":"").$fromcompany->email;
872
		}
873
	}
874
	if ($showdetails == 2 || $showdetails == 3 || ($fromcompany->country_code == 'DE'))
875
	{
876
		// Managers
877
		if ($fromcompany->managers)
878
		{
879
			$line2.=($line2?" - ":"").$fromcompany->managers;
880
		}
881
	}
882
883
	// Line 3 of company infos
884
	// Juridical status
885
	if ($fromcompany->forme_juridique_code)
886
	{
887
		$line3.=($line3?" - ":"").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code));
888
	}
889
	// Capital
890
	if ($fromcompany->capital)
891
	{
892
		$tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string
893
		if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) $line3.=($line3?" - ":"").$outputlangs->transnoentities("CapitalOf",price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency));
894
		else $line3.=($line3?" - ":"").$outputlangs->transnoentities("CapitalOf",$tmpamounttoshow,$outputlangs);
895
	}
896
	// Prof Id 1
897
	if ($fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || ! $fromcompany->idprof2))
898
	{
899
		$field=$outputlangs->transcountrynoentities("ProfId1",$fromcompany->country_code);
900
		if (preg_match('/\((.*)\)/i',$field,$reg)) $field=$reg[1];
901
		$line3.=($line3?" - ":"").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1);
902
	}
903
	// Prof Id 2
904
	if ($fromcompany->idprof2)
905
	{
906
		$field=$outputlangs->transcountrynoentities("ProfId2",$fromcompany->country_code);
907
		if (preg_match('/\((.*)\)/i',$field,$reg)) $field=$reg[1];
908
		$line3.=($line3?" - ":"").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof2);
909
	}
910
911
	// Line 4 of company infos
912
	// Prof Id 3
913
	if ($fromcompany->idprof3)
914
	{
915
		$field=$outputlangs->transcountrynoentities("ProfId3",$fromcompany->country_code);
916
		if (preg_match('/\((.*)\)/i',$field,$reg)) $field=$reg[1];
917
		$line4.=($line4?" - ":"").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3);
918
	}
919
	// Prof Id 4
920
	if ($fromcompany->idprof4)
921
	{
922
		$field=$outputlangs->transcountrynoentities("ProfId4",$fromcompany->country_code);
923
		if (preg_match('/\((.*)\)/i',$field,$reg)) $field=$reg[1];
924
		$line4.=($line4?" - ":"").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4);
925
	}
926
	// Prof Id 5
927
	if ($fromcompany->idprof5)
928
	{
929
		$field=$outputlangs->transcountrynoentities("ProfId5",$fromcompany->country_code);
930
		if (preg_match('/\((.*)\)/i',$field,$reg)) $field=$reg[1];
931
		$line4.=($line4?" - ":"").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5);
932
	}
933
	// Prof Id 6
934
	if ($fromcompany->idprof6)
935
	{
936
		$field=$outputlangs->transcountrynoentities("ProfId6",$fromcompany->country_code);
937
		if (preg_match('/\((.*)\)/i',$field,$reg)) $field=$reg[1];
938
		$line4.=($line4?" - ":"").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6);
939
	}
940
	// IntraCommunautary VAT
941
	if ($fromcompany->tva_intra != '')
942
	{
943
		$line4.=($line4?" - ":"").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra);
944
	}
945
946
	$pdf->SetFont('','',7);
947
	$pdf->SetDrawColor(224,224,224);
948
949
	// The start of the bottom of this page footer is positioned according to # of lines
950
	$freetextheight=0;
951
	if ($line)	// Free text
952
	{
953
		//$line="sample text<br>\nfd<strong>sf</strong>sdf<br>\nghfghg<br>";
954
	    if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT))
955
		{
956
			$width=20000; $align='L';	// By default, ask a manual break: We use a large value 20000, to not have automatic wrap. This make user understand, he need to add CR on its text.
957
    		if (! empty($conf->global->MAIN_USE_AUTOWRAP_ON_FREETEXT)) {
958
    			$width=200; $align='C';
959
    		}
960
		    $freetextheight=$pdf->getStringHeight($width,$line);
961
		}
962
		else
963
		{
964
            $freetextheight=pdfGetHeightForHtmlContent($pdf,dol_htmlentitiesbr($line, 1, 'UTF-8', 0));      // New method (works for HTML content)
965
            //print '<br>'.$freetextheight;exit;
966
		}
967
	}
968
969
	$marginwithfooter=$marge_basse + $freetextheight + (! empty($line1)?3:0) + (! empty($line2)?3:0) + (! empty($line3)?3:0) + (! empty($line4)?3:0);
970
	$posy=$marginwithfooter+0;
971
972
	if ($line)	// Free text
973
	{
974
		$pdf->SetXY($dims['lm'],-$posy);
975
		if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT))   // by default
976
		{
977
            $pdf->MultiCell(0, 3, $line, 0, $align, 0);
0 ignored issues
show
Bug introduced by
The variable $align 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...
978
		}
979
		else
980
		{
981
            $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk']-$marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0));
982
		}
983
		$posy-=$freetextheight;
984
	}
985
986
	$pdf->SetY(-$posy);
987
	$pdf->line($dims['lm'], $dims['hk']-$posy, $dims['wk']-$dims['rm'], $dims['hk']-$posy);
988
	$posy--;
989
990
	if (! empty($line1))
991
	{
992
		$pdf->SetFont('','B',7);
993
		$pdf->SetXY($dims['lm'],-$posy);
994
		$pdf->MultiCell($dims['wk']-$dims['rm']-$dims['lm'], 2, $line1, 0, 'C', 0);
995
		$posy-=3;
996
		$pdf->SetFont('','',7);
997
	}
998
999
	if (! empty($line2))
1000
	{
1001
		$pdf->SetFont('','B',7);
1002
		$pdf->SetXY($dims['lm'],-$posy);
1003
		$pdf->MultiCell($dims['wk']-$dims['rm']-$dims['lm'], 2, $line2, 0, 'C', 0);
1004
		$posy-=3;
1005
		$pdf->SetFont('','',7);
1006
	}
1007
1008
	if (! empty($line3))
1009
	{
1010
		$pdf->SetXY($dims['lm'],-$posy);
1011
		$pdf->MultiCell($dims['wk']-$dims['rm']-$dims['lm'], 2, $line3, 0, 'C', 0);
1012
	}
1013
1014
	if (! empty($line4))
1015
	{
1016
		$posy-=3;
1017
		$pdf->SetXY($dims['lm'],-$posy);
1018
		$pdf->MultiCell($dims['wk']-$dims['rm']-$dims['lm'], 2, $line4, 0, 'C', 0);
1019
	}
1020
1021
	// Show page nb only on iso languages (so default Helvetica font)
1022
	if (strtolower(pdf_getPDFFont($outputlangs)) == 'helvetica')
1023
	{
1024
		$pdf->SetXY($dims['wk']-$dims['rm']-15, -$posy);
1025
		//print 'xxx'.$pdf->PageNo().'-'.$pdf->getAliasNbPages().'-'.$pdf->getAliasNumPage();exit;
1026
		$pdf->MultiCell(15, 2, $pdf->PageNo().'/'.$pdf->getAliasNbPages(), 0, 'R', 0);
1027
	}
1028
1029
	return $marginwithfooter;
1030
}
1031
1032
/**
1033
 *	Show linked objects for PDF generation
1034
 *
1035
 *	@param	TCPDF			$pdf				Object PDF
1036
 *	@param	object		$object				Object
1037
 *	@param  Translate	$outputlangs		Object lang
1038
 *	@param  int			$posx				X
1039
 *	@param  int			$posy				Y
1040
 *	@param	float		$w					Width of cells. If 0, they extend up to the right margin of the page.
1041
 *	@param	float		$h					Cell minimum height. The cell extends automatically if needed.
1042
 *	@param	int			$align				Align
1043
 *	@param	string		$default_font_size	Font size
1044
 *	@return	float                           The Y PDF position
1045
 */
1046
function pdf_writeLinkedObjects(&$pdf,$object,$outputlangs,$posx,$posy,$w,$h,$align,$default_font_size)
1047
{
1048
	$linkedobjects = pdf_getLinkedObjects($object,$outputlangs);
1049
	if (! empty($linkedobjects))
1050
	{
1051
		foreach($linkedobjects as $linkedobject)
1052
		{
1053
		    $reftoshow = $linkedobject["ref_title"].' : '.$linkedobject["ref_value"];
1054
		    if (! empty($linkedobject["date_value"]))
1055
		    {
1056
		        $reftoshow .= ' / '.$linkedobject["date_value"];
1057
		    }
1058
1059
			$posy+=3;
1060
			$pdf->SetXY($posx,$posy);
1061
			$pdf->SetFont('','', $default_font_size - 2);
1062
			$pdf->MultiCell($w, $h, $reftoshow, '', $align);
1063
		}
1064
	}
1065
1066
	return $pdf->getY();
1067
}
1068
1069
/**
1070
 *	Output line description into PDF
1071
 *
1072
 *  @param  TCPDF				$pdf               PDF object
1073
 *	@param	Object			$object				Object
1074
 *	@param	int				$i					Current line number
1075
 *  @param  Translate		$outputlangs		Object lang for output
1076
 *  @param  int				$w					Width
1077
 *  @param  int				$h					Height
1078
 *  @param  int				$posx				Pos x
1079
 *  @param  int				$posy				Pos y
1080
 *  @param  int				$hideref       		Hide reference
1081
 *  @param  int				$hidedesc           Hide description
1082
 * 	@param	int				$issupplierline		Is it a line for a supplier object ?
1083
 * 	@return	string
1084
 */
1085
function pdf_writelinedesc(&$pdf,$object,$i,$outputlangs,$w,$h,$posx,$posy,$hideref=0,$hidedesc=0,$issupplierline=0)
1086
{
1087
	global $db, $conf, $langs, $hookmanager;
1088
1089
	$reshook=0;
1090
	$result='';
1091
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1092
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1093
	{
1094
		$special_code = $object->lines[$i]->special_code;
1095
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1096
		$parameters = array('pdf'=>$pdf,'i'=>$i,'outputlangs'=>$outputlangs,'w'=>$w,'h'=>$h,'posx'=>$posx,'posy'=>$posy,'hideref'=>$hideref,'hidedesc'=>$hidedesc,'issupplierline'=>$issupplierline,'special_code'=>$special_code);
1097
		$action='';
1098
		$reshook=$hookmanager->executeHooks('pdf_writelinedesc',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1099
1100
		if (!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1101
	}
1102
	if (empty($reshook))
1103
	{
1104
		$labelproductservice=pdf_getlinedesc($object,$i,$outputlangs,$hideref,$hidedesc,$issupplierline);
1105
		// Description
1106
		$pdf->writeHTMLCell($w, $h, $posx, $posy, $outputlangs->convToOutputCharset($labelproductservice), 0, 1, false, true, 'J',true);
1107
		$result.=$labelproductservice;
1108
	}
1109
	return $result;
1110
}
1111
1112
/**
1113
 *  Return line description translated in outputlangs and encoded into htmlentities and with <br>
1114
 *
1115
 *  @param  Object		$object              Object
1116
 *  @param  int			$i                   Current line number (0 = first line, 1 = second line, ...)
1117
 *  @param  Translate	$outputlangs         Object langs for output
1118
 *  @param  int			$hideref             Hide reference
1119
 *  @param  int			$hidedesc            Hide description
1120
 *  @param  int			$issupplierline      Is it a line for a supplier object ?
1121
 *  @return string       				     String with line
1122
 */
1123
function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issupplierline=0)
1124
{
1125
	global $db, $conf, $langs;
1126
1127
	$idprod=(! empty($object->lines[$i]->fk_product)?$object->lines[$i]->fk_product:false);
1128
	$label=(! empty($object->lines[$i]->label)?$object->lines[$i]->label:(! empty($object->lines[$i]->product_label)?$object->lines[$i]->product_label:''));
1129
	$desc=(! empty($object->lines[$i]->desc)?$object->lines[$i]->desc:(! empty($object->lines[$i]->description)?$object->lines[$i]->description:''));
1130
	$ref_supplier=(! empty($object->lines[$i]->ref_supplier)?$object->lines[$i]->ref_supplier:(! empty($object->lines[$i]->ref_fourn)?$object->lines[$i]->ref_fourn:''));    // TODO Not yet saved for supplier invoices, only supplier orders
1131
	$note=(! empty($object->lines[$i]->note)?$object->lines[$i]->note:'');
1132
	$dbatch=(! empty($object->lines[$i]->detail_batch)?$object->lines[$i]->detail_batch:false);
1133
1134
	if ($issupplierline) $prodser = new ProductFournisseur($db);
1135
	else $prodser = new Product($db);
1136
1137
	if ($idprod)
1138
	{
1139
		$prodser->fetch($idprod);
1140
		// If a predefined product and multilang and on other lang, we renamed label with label translated
1141
		if (! empty($conf->global->MAIN_MULTILANGS) && ($outputlangs->defaultlang != $langs->defaultlang))
1142
		{
1143
			$translatealsoifmodified=(! empty($conf->global->MAIN_MULTILANG_TRANSLATE_EVEN_IF_MODIFIED));	// By default if value was modified manually, we keep it (no translation because we don't have it)
1144
1145
			// TODO Instead of making a compare to see if param was modified, check that content contains reference translation. If yes, add the added part to the new translation
1146
			// ($textwasmodified is replaced with $textwasmodifiedorcompleted and we add completion).
1147
1148
			// Set label
1149
			// If we want another language, and if label is same than default language (we did force it to a specific value), we can use translation.
1150
			//var_dump($outputlangs->defaultlang.' - '.$langs->defaultlang.' - '.$label.' - '.$prodser->label);exit;
1151
			$textwasmodified=($label == $prodser->label);
1152
			if (! empty($prodser->multilangs[$outputlangs->defaultlang]["label"]) && ($textwasmodified || $translatealsoifmodified))     $label=$prodser->multilangs[$outputlangs->defaultlang]["label"];
1153
1154
			// Set desc
1155
			// Manage HTML entities description test because $prodser->description is store with htmlentities but $desc no
1156
			$textwasmodified=false;
1157
			if (!empty($desc) && dol_textishtml($desc) && !empty($prodser->description) && dol_textishtml($prodser->description)) {
1158
				$textwasmodified=(strpos(dol_html_entity_decode($desc,ENT_QUOTES | ENT_HTML401),dol_html_entity_decode($prodser->description,ENT_QUOTES | ENT_HTML401))!==false);
1159
			} else {
1160
				$textwasmodified=($desc == $prodser->description);
1161
			}
1162
			if (! empty($prodser->multilangs[$outputlangs->defaultlang]["description"]) && ($textwasmodified || $translatealsoifmodified))  $desc=$prodser->multilangs[$outputlangs->defaultlang]["description"];
1163
1164
			// Set note
1165
			$textwasmodified=($note == $prodser->note);
1166
			if (! empty($prodser->multilangs[$outputlangs->defaultlang]["note"]) && ($textwasmodified || $translatealsoifmodified))  $note=$prodser->multilangs[$outputlangs->defaultlang]["note"];
1167
		}
1168
	}
1169
1170
	// Description short of product line
1171
	$libelleproduitservice=$label;
1172
1173
	// Description long of product line
1174
	if (! empty($desc) && ($desc != $label))
1175
	{
1176
		if ($libelleproduitservice && empty($hidedesc))
1177
		{
1178
			$libelleproduitservice.='__N__';
1179
		}
1180
1181
		if ($desc == '(CREDIT_NOTE)' && $object->lines[$i]->fk_remise_except)
1182
		{
1183
			$discount=new DiscountAbsolute($db);
1184
			$discount->fetch($object->lines[$i]->fk_remise_except);
1185
			$sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
1186
			$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$sourceref);
1187
		}
1188
		elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except)
1189
		{
1190
			$discount=new DiscountAbsolute($db);
1191
			$discount->fetch($object->lines[$i]->fk_remise_except);
1192
			$sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
1193
			$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$sourceref);
1194
			// Add date of deposit
1195
			if (! empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) echo ' ('.dol_print_date($discount->datec,'day','',$outputlangs).')';
1196
		}
1197
		if ($desc == '(EXCESS RECEIVED)' && $object->lines[$i]->fk_remise_except)
1198
		{
1199
			$discount=new DiscountAbsolute($db);
1200
			$discount->fetch($object->lines[$i]->fk_remise_except);
1201
			$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
1202
		}
1203
		elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except)
1204
		{
1205
			$discount=new DiscountAbsolute($db);
1206
			$discount->fetch($object->lines[$i]->fk_remise_except);
1207
			$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid",$discount->ref_invoice_supplier_source);
1208
		}
1209
		else
1210
		{
1211
			if ($idprod)
1212
			{
1213
				if (empty($hidedesc)) $libelleproduitservice.=$desc;
1214
			}
1215
			else
1216
			{
1217
				$libelleproduitservice.=$desc;
1218
			}
1219
		}
1220
	}
1221
1222
	// We add ref of product (and supplier ref if defined)
1223
	$prefix_prodserv = "";
1224
	$ref_prodserv = "";
1225
	if (! empty($conf->global->PRODUCT_ADD_TYPE_IN_DOCUMENTS))   // In standard mode, we do not show this
1226
	{
1227
		if ($prodser->isService())
1228
		{
1229
			$prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." ";
1230
		}
1231
		else
1232
		{
1233
			$prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." ";
1234
		}
1235
	}
1236
1237
	if (empty($hideref))
1238
	{
1239
		if ($issupplierline)
1240
		{
1241
			if ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 1)
1242
				$ref_prodserv = $ref_supplier;
1243
			elseif ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 2)
1244
				$ref_prodserv = $ref_supplier. ' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')';
1245
			else	// Common case
1246
			{
1247
				$ref_prodserv = $prodser->ref; // Show local ref
1248
				if ($ref_supplier) $ref_prodserv.= ($prodser->ref?' (':'').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref?')':'');
1249
			}
1250
		}
1251
		else
1252
		{
1253
			$ref_prodserv = $prodser->ref; // Show local ref only
1254
		}
1255
1256
		if (! empty($libelleproduitservice) && ! empty($ref_prodserv)) $ref_prodserv .= " - ";
1257
	}
1258
1259
	$libelleproduitservice=$prefix_prodserv.$ref_prodserv.$libelleproduitservice;
1260
1261
	// Add an additional description for the category products
1262
	if (! empty($conf->global->CATEGORY_ADD_DESC_INTO_DOC) && $idprod && ! empty($conf->categorie->enabled))
1263
	{
1264
		include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1265
		$categstatic=new Categorie($db);
1266
		// recovering the list of all the categories linked to product
1267
		$tblcateg=$categstatic->containing($idprod, Categorie::TYPE_PRODUCT);
1268
		foreach ($tblcateg as $cate)
1269
		{
1270
			// Adding the descriptions if they are filled
1271
			$desccateg=$cate->add_description;
1272
			if ($desccateg)
1273
				$libelleproduitservice.='__N__'.$desccateg;
1274
		}
1275
	}
1276
1277
	if (! empty($object->lines[$i]->date_start) || ! empty($object->lines[$i]->date_end))
1278
	{
1279
		$format='day';
1280
		// Show duration if exists
1281
		if ($object->lines[$i]->date_start && $object->lines[$i]->date_end)
1282
		{
1283
			$period='('.$outputlangs->transnoentitiesnoconv('DateFromTo',dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs),dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1284
		}
1285
		if ($object->lines[$i]->date_start && ! $object->lines[$i]->date_end)
1286
		{
1287
			$period='('.$outputlangs->transnoentitiesnoconv('DateFrom',dol_print_date($object->lines[$i]->date_start, $format, false, $outputlangs)).')';
1288
		}
1289
		if (! $object->lines[$i]->date_start && $object->lines[$i]->date_end)
1290
		{
1291
			$period='('.$outputlangs->transnoentitiesnoconv('DateUntil',dol_print_date($object->lines[$i]->date_end, $format, false, $outputlangs)).')';
1292
		}
1293
		//print '>'.$outputlangs->charset_output.','.$period;
1294
		$libelleproduitservice.="__N__".$period;
0 ignored issues
show
Bug introduced by
The variable $period 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...
1295
		//print $libelleproduitservice;
1296
	}
1297
1298
	if ($dbatch)
1299
	{
1300
		$format='day';
1301
		foreach ($dbatch as $detail)
1302
		{
1303
			$dte=array();
1304
			if ($detail->eatby) $dte[]=$outputlangs->transnoentitiesnoconv('printEatby',dol_print_date($detail->eatby, $format, false, $outputlangs));
1305
			if ($detail->sellby) $dte[]=$outputlangs->transnoentitiesnoconv('printSellby',dol_print_date($detail->sellby, $format, false, $outputlangs));
1306
			if ($detail->batch) $dte[]=$outputlangs->transnoentitiesnoconv('printBatch',$detail->batch);
1307
			$dte[]=$outputlangs->transnoentitiesnoconv('printQty',$detail->dluo_qty);
1308
			$libelleproduitservice.= "__N__  ".implode(" - ", $dte);
1309
		}
1310
	}
1311
1312
	// Now we convert \n into br
1313
	if (dol_textishtml($libelleproduitservice)) $libelleproduitservice=preg_replace('/__N__/','<br>',$libelleproduitservice);
1314
	else $libelleproduitservice=preg_replace('/__N__/',"\n",$libelleproduitservice);
1315
	$libelleproduitservice=dol_htmlentitiesbr($libelleproduitservice,1);
1316
1317
	return $libelleproduitservice;
1318
}
1319
1320
/**
1321
 *	Return line num
1322
 *
1323
 *	@param	Object		$object				Object
1324
 *	@param	int			$i					Current line number
1325
 *  @param  Translate	$outputlangs		Object langs for output
1326
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1327
 * 	@return	string
1328
 */
1329
function pdf_getlinenum($object,$i,$outputlangs,$hidedetails=0)
1330
{
1331
	global $hookmanager;
1332
1333
	$reshook=0;
1334
	$result='';
1335
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1336
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1337
	{
1338
		$special_code = $object->lines[$i]->special_code;
1339
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1340
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1341
		$action='';
1342
		$reshook = $hookmanager->executeHooks('pdf_getlinenum',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1343
		$result.=$hookmanager->resPrint;
1344
	}
1345
	if (empty($reshook))
1346
	{
1347
		$result.=dol_htmlentitiesbr($object->lines[$i]->num);
1348
	}
1349
	return $result;
1350
}
1351
1352
1353
/**
1354
 *	Return line product ref
1355
 *
1356
 *	@param	Object		$object				Object
1357
 *	@param	int			$i					Current line number
1358
 *  @param  Translate	$outputlangs		Object langs for output
1359
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1360
 * 	@return	string
1361
 */
1362
function pdf_getlineref($object,$i,$outputlangs,$hidedetails=0)
1363
{
1364
	global $hookmanager;
1365
1366
	$reshook=0;
1367
	$result='';
1368
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1369
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1370
	{
1371
		$special_code = $object->lines[$i]->special_code;
1372
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1373
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1374
		$action='';
1375
		$reshook = $hookmanager->executeHooks('pdf_getlineref',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1376
		$result.=$hookmanager->resPrint;
1377
	}
1378
	if (empty($reshook))
1379
	{
1380
		$result.=dol_htmlentitiesbr($object->lines[$i]->product_ref);
1381
	}
1382
	return $result;
1383
}
1384
1385
/**
1386
 *	Return line ref_supplier
1387
 *
1388
 *	@param	Object		$object				Object
1389
 *	@param	int			$i					Current line number
1390
 *  @param  Translate	$outputlangs		Object langs for output
1391
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1392
 * 	@return	string
1393
 */
1394
function pdf_getlineref_supplier($object,$i,$outputlangs,$hidedetails=0)
1395
{
1396
	global $hookmanager;
1397
1398
	$reshook=0;
1399
	$result='';
1400
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1401
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1402
	{
1403
		$special_code = $object->lines[$i]->special_code;
1404
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1405
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1406
		$action='';
1407
		$reshook = $hookmanager->executeHooks('pdf_getlineref_supplier',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1408
		$result.=$hookmanager->resPrint;
1409
	}
1410
	if (empty($reshook))
1411
	{
1412
		$result.=dol_htmlentitiesbr($object->lines[$i]->ref_supplier);
1413
	}
1414
	return $result;
1415
}
1416
1417
/**
1418
 *	Return line vat rate
1419
 *
1420
 *	@param	Object		$object				Object
1421
 *	@param	int			$i					Current line number
1422
 *  @param  Translate	$outputlangs		Object langs for output
1423
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1424
 * 	@return	string
1425
 */
1426
function pdf_getlinevatrate($object,$i,$outputlangs,$hidedetails=0)
1427
{
1428
	global $conf, $hookmanager, $mysoc;
1429
1430
	$result='';
1431
	$reshook=0;
1432
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1433
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduce this test in the pdf_xxx function if you don't want your hook to run
1434
	{
1435
		$special_code = $object->lines[$i]->special_code;
1436
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1437
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1438
		$action='';
1439
		$reshook = $hookmanager->executeHooks('pdf_getlinevatrate',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1440
1441
		if (!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1442
	}
1443
	if (empty($reshook))
1444
	{
1445
		if (empty($hidedetails) || $hidedetails > 1)
1446
		{
1447
			$tmpresult='';
1448
1449
			$tmpresult.=vatrate($object->lines[$i]->tva_tx, 0, $object->lines[$i]->info_bits, -1);
1450
			if (empty($conf->global->MAIN_PDF_MAIN_HIDE_SECOND_TAX))
1451
			{
1452
				if ($object->lines[$i]->total_localtax1 != 0)
1453
				{
1454
					if (preg_replace('/[\s0%]/','',$tmpresult)) $tmpresult.='/';
1455
					else $tmpresult='';
1456
					$tmpresult.=vatrate(abs($object->lines[$i]->localtax1_tx), 0);
1457
				}
1458
			}
1459
			if (empty($conf->global->MAIN_PDF_MAIN_HIDE_THIRD_TAX))
1460
			{
1461
				if ($object->lines[$i]->total_localtax2 != 0)
1462
				{
1463
					if (preg_replace('/[\s0%]/','',$tmpresult)) $tmpresult.='/';
1464
					else $tmpresult='';
1465
					$tmpresult.=vatrate(abs($object->lines[$i]->localtax2_tx), 0);
1466
				}
1467
			}
1468
			$tmpresult.= '%';
1469
1470
			$result.=$tmpresult;
1471
		}
1472
	}
1473
	return $result;
1474
}
1475
1476
/**
1477
 *	Return line unit price excluding tax
1478
 *
1479
 *	@param	Object		$object				Object
1480
 *	@param	int			$i					Current line number
1481
 *  @param  Translate	$outputlangs		Object langs for output
1482
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1483
 * 	@return	string
1484
 */
1485
function pdf_getlineupexcltax($object,$i,$outputlangs,$hidedetails=0)
1486
{
1487
	global $conf, $hookmanager;
1488
1489
	$sign=1;
1490
	if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
1491
1492
	$result='';
1493
	$reshook=0;
1494
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1495
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1496
	{
1497
		$special_code = $object->lines[$i]->special_code;
1498
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1499
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1500
		$action='';
1501
		$reshook = $hookmanager->executeHooks('pdf_getlineupexcltax',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1502
1503
		if (!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1504
	}
1505
	if (empty($reshook))
1506
	{
1507
		if (empty($hidedetails) || $hidedetails > 1)
1508
		{
1509
			$subprice = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_subprice : $object->lines[$i]->subprice);
1510
			$result.=price($sign * $subprice, 0, $outputlangs);
1511
		}
1512
	}
1513
	return $result;
1514
}
1515
1516
/**
1517
 *	Return line unit price including tax
1518
 *
1519
 *	@param	Object		$object				Object
1520
 *	@param	int			$i					Current line number
1521
 *  @param  Translate	$outputlangs		Object langs for output
1522
 *  @param	int			$hidedetails		Hide value (0 = no,	1 = yes, 2 = just special lines)
1523
 *  @return	string
1524
 */
1525
function pdf_getlineupwithtax($object,$i,$outputlangs,$hidedetails=0)
1526
{
1527
	global $hookmanager,$conf;
1528
1529
	$sign=1;
1530
	if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
1531
1532
	$result='';
1533
	$reshook=0;
1534
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1535
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1536
	{
1537
		$special_code = $object->lines[$i]->special_code;
1538
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1539
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1540
		$action='';
1541
		$reshook = $hookmanager->executeHooks('pdf_getlineupwithtax',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1542
1543
		if (!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1544
	}
1545
	if (empty($reshook))
1546
	{
1547
		if (empty($hidedetails) || $hidedetails > 1) $result.=price($sign * (($object->lines[$i]->subprice) + ($object->lines[$i]->subprice)*($object->lines[$i]->tva_tx)/100), 0, $outputlangs);
1548
	}
1549
	return $result;
1550
}
1551
1552
/**
1553
 *	Return line quantity
1554
 *
1555
 *	@param	Object		$object				Object
1556
 *	@param	int			$i					Current line number
1557
 *  @param  Translate	$outputlangs		Object langs for output
1558
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1559
 *  @return	string
1560
 */
1561
function pdf_getlineqty($object,$i,$outputlangs,$hidedetails=0)
1562
{
1563
	global $hookmanager;
1564
1565
	$result='';
1566
	$reshook=0;
1567
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1568
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1569
	{
1570
		$special_code = $object->lines[$i]->special_code;
1571
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1572
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1573
		$action='';
1574
		$reshook = $hookmanager->executeHooks('pdf_getlineqty',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1575
1576
		if(!empty($hookmanager->resPrint)) $result=$hookmanager->resPrint;
1577
	}
1578
    if (empty($reshook))
1579
	{
1580
	   if ($object->lines[$i]->special_code == 3) return '';
1581
	   if (empty($hidedetails) || $hidedetails > 1) $result.=$object->lines[$i]->qty;
1582
	}
1583
	return $result;
1584
}
1585
1586
/**
1587
 *	Return line quantity asked
1588
 *
1589
 *	@param	Object		$object				Object
1590
 *	@param	int			$i					Current line number
1591
 *  @param  Translate	$outputlangs		Object langs for output
1592
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1593
 * 	@return	string
1594
 */
1595
function pdf_getlineqty_asked($object,$i,$outputlangs,$hidedetails=0)
1596
{
1597
	global $hookmanager;
1598
1599
	$reshook=0;
1600
	$result='';
1601
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1602
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1603
	{
1604
		$special_code = $object->lines[$i]->special_code;
1605
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1606
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1607
		$action='';
1608
		$reshook = $hookmanager->executeHooks('pdf_getlineqty_asked',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1609
1610
		if (!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1611
	}
1612
	if (empty($reshook))
1613
	{
1614
        if ($object->lines[$i]->special_code == 3) return '';
1615
        if (empty($hidedetails) || $hidedetails > 1) $result.=$object->lines[$i]->qty_asked;
1616
	}
1617
	return $result;
1618
}
1619
1620
/**
1621
 *	Return line quantity shipped
1622
 *
1623
 *	@param	Object		$object				Object
1624
 *	@param	int			$i					Current line number
1625
 *  @param  Translate	$outputlangs		Object langs for output
1626
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1627
 * 	@return	string
1628
 */
1629
function pdf_getlineqty_shipped($object,$i,$outputlangs,$hidedetails=0)
1630
{
1631
	global $hookmanager;
1632
1633
	$reshook=0;
1634
	$result='';
1635
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1636
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1637
	{
1638
		$special_code = $object->lines[$i]->special_code;
1639
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1640
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1641
		$action='';
1642
		$reshook = $hookmanager->executeHooks('pdf_getlineqty_shipped',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1643
1644
		if(!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1645
	}
1646
	if (empty($reshook))
1647
	{
1648
        if ($object->lines[$i]->special_code == 3) return '';
1649
	    if (empty($hidedetails) || $hidedetails > 1) $result.=$object->lines[$i]->qty_shipped;
1650
	}
1651
	return $result;
1652
}
1653
1654
/**
1655
 *	Return line keep to ship quantity
1656
 *
1657
 *	@param	Object		$object				Object
1658
 *	@param	int			$i					Current line number
1659
 *  @param  Translate	$outputlangs		Object langs for output
1660
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1661
 * 	@return	string
1662
 */
1663
function pdf_getlineqty_keeptoship($object,$i,$outputlangs,$hidedetails=0)
1664
{
1665
	global $hookmanager;
1666
1667
	$reshook=0;
1668
    $result='';
1669
    //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1670
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1671
	{
1672
		$special_code = $object->lines[$i]->special_code;
1673
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1674
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1675
		$action='';
1676
		$reshook = $hookmanager->executeHooks('pdf_getlineqty_keeptoship',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1677
1678
		if(!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1679
	}
1680
	if (empty($reshook))
1681
	{
1682
        if ($object->lines[$i]->special_code == 3) return '';
1683
		if (empty($hidedetails) || $hidedetails > 1) $result.=($object->lines[$i]->qty_asked - $object->lines[$i]->qty_shipped);
1684
	}
1685
	return $result;
1686
}
1687
1688
/**
1689
 *	Return line unit
1690
 *
1691
 *	@param	Object		$object				Object
1692
 *	@param	int			$i					Current line number
1693
 *  @param  Translate	$outputlangs		Object langs for output
1694
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1695
 *  @param	HookManager	$hookmanager		Hook manager instance
1696
 *  @return	string							Value for unit cell
1697
 */
1698
function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = false)
1699
{
1700
	global $langs;
1701
1702
	$reshook=0;
1703
    $result='';
1704
    //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1705
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1706
	{
1707
		$special_code = $object->lines[$i]->special_code;
1708
		if (!empty($object->lines[$i]->fk_parent_line)) {
1709
			$special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1710
		}
1711
		$parameters = array(
1712
			'i' => $i,
1713
			'outputlangs' => $outputlangs,
1714
			'hidedetails' => $hidedetails,
1715
			'special_code' => $special_code
1716
		);
1717
		$action = '';
1718
		$reshook = $hookmanager->executeHooks('pdf_getlineunit', $parameters, $object, $action);    // Note that $action and $object may have been modified by some hooks
1719
1720
		if(!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1721
	}
1722
	if (empty($reshook))
1723
	{
1724
        if ($object->lines[$i]->special_code == 3) return '';
1725
	    if (empty($hidedetails) || $hidedetails > 1) $result.=$langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short'));
1726
	}
1727
	return $result;
1728
}
1729
1730
1731
/**
1732
 *	Return line remise percent
1733
 *
1734
 *	@param	Object		$object				Object
1735
 *	@param	int			$i					Current line number
1736
 *  @param  Translate	$outputlangs		Object langs for output
1737
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1738
 * 	@return	string
1739
 */
1740
function pdf_getlineremisepercent($object,$i,$outputlangs,$hidedetails=0)
1741
{
1742
	global $hookmanager;
1743
1744
	include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1745
1746
	$reshook=0;
1747
	$result='';
1748
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1749
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1750
	{
1751
		$special_code = $object->lines[$i]->special_code;
1752
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1753
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1754
		$action='';
1755
		$reshook = $hookmanager->executeHooks('pdf_getlineremisepercent',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1756
1757
		if(!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1758
	}
1759
	if (empty($reshook))
1760
	{
1761
        if ($object->lines[$i]->special_code == 3) return '';
1762
	    if (empty($hidedetails) || $hidedetails > 1) $result.=dol_print_reduction($object->lines[$i]->remise_percent,$outputlangs);
1763
	}
1764
	return $result;
1765
}
1766
1767
/**
1768
 * Return line percent
1769
 *
1770
 * @param Object $object Object
1771
 * @param int $i Current line number
1772
 * @param Translate $outputlangs Object langs for output
1773
 * @param int $hidedetails Hide details (0=no, 1=yes, 2=just special lines)
1774
 * @param HookManager $hookmanager Hook manager instance
1775
 * @return string
1776
 */
1777
function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
1778
{
1779
	if (empty($hookmanager)) global $hookmanager;
1780
1781
	$reshook=0;
1782
    $result='';
1783
    //if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1784
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1785
	{
1786
		$special_code = $object->lines[$i]->special_code;
1787
		if (!empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1788
		$parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
1789
		$action = '';
1790
		$reshook = $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action);    // Note that $action and $object may have been modified by some hooks
1791
1792
		if(!empty($hookmanager->resPrint)) return $hookmanager->resPrint;
1793
	}
1794
	if (empty($reshook))
1795
	{
1796
        	if ($object->lines[$i]->special_code == 3) return '';
1797
		if (empty($hidedetails) || $hidedetails > 1)
1798
		{
1799
			if ($conf->global->SITUATION_DISPLAY_DIFF_ON_PDF)
0 ignored issues
show
Bug introduced by
The variable $conf 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...
1800
			{
1801
				$prev_progress = 0;
1802
				if (method_exists($object, 'get_prev_progress'))
1803
				{
1804
			 		$prev_progress = $object->lines[$i]->get_prev_progress($object->id);
1805
				}
1806
			 	$result = ($object->lines[$i]->situation_percent - $prev_progress) . '%';
1807
			}
1808
			else
1809
				$result = $object->lines[$i]->situation_percent . '%';
1810
	  	}
1811
	}
1812
	return $result;
1813
}
1814
1815
/**
1816
 *	Return line total excluding tax
1817
 *
1818
 *	@param	Object		$object				Object
1819
 *	@param	int			$i					Current line number
1820
 *  @param  Translate	$outputlangs		Object langs for output
1821
 *  @param	int			$hidedetails		Hide details (0=no, 1=yes, 2=just special lines)
1822
 * 	@return	string							Return total of line excl tax
1823
 */
1824
function pdf_getlinetotalexcltax($object,$i,$outputlangs,$hidedetails=0)
1825
{
1826
	global $conf, $hookmanager;
1827
1828
	$sign=1;
1829
	if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
1830
1831
	$reshook=0;
1832
	$result='';
1833
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1834
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1835
	{
1836
		$special_code = $object->lines[$i]->special_code;
1837
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1838
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code, 'sign'=>$sign);
1839
		$action='';
1840
		$reshook = $hookmanager->executeHooks('pdf_getlinetotalexcltax',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1841
1842
		if(!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1843
	}
1844
    if (empty($reshook))
1845
    {
1846
	    if ($object->lines[$i]->special_code == 3)
1847
    	{
1848
    		return $outputlangs->transnoentities("Option");
1849
    	}
1850
        if (empty($hidedetails) || $hidedetails > 1)
1851
        {
1852
        	$total_ht = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
1853
        	if ($object->lines[$i]->situation_percent > 0)
1854
        	{
1855
        		$prev_progress = 0;
1856
        		$progress = 1;
1857
        		if (method_exists($object, 'get_prev_progress'))
1858
        		{
1859
					$prev_progress = $object->lines[$i]->get_prev_progress($object->id);
1860
					$progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
1861
        		}
1862
				$result.=price($sign * ($total_ht/($object->lines[$i]->situation_percent/100)) * $progress, 0, $outputlangs);
1863
			}
1864
        	else
1865
			$result.=price($sign * $total_ht, 0, $outputlangs);
1866
	}
1867
    }
1868
	return $result;
1869
}
1870
1871
/**
1872
 *	Return line total including tax
1873
 *
1874
 *	@param	Object		$object				Object
1875
 *	@param	int			$i					Current line number
1876
 *  @param 	Translate	$outputlangs		Object langs for output
1877
 *  @param	int			$hidedetails		Hide value (0 = no, 1 = yes, 2 = just special lines)
1878
 *  @return	string							Return total of line incl tax
1879
 */
1880
function pdf_getlinetotalwithtax($object,$i,$outputlangs,$hidedetails=0)
1881
{
1882
	global $hookmanager,$conf;
1883
1884
	$sign=1;
1885
	if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
1886
1887
	$reshook=0;
1888
	$result='';
1889
	//if (is_object($hookmanager) && ( (isset($object->lines[$i]->product_type) && $object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line) ) )
1890
	if (is_object($hookmanager))   // Old code is commented on preceding line. Reproduct this test in the pdf_xxx function if you don't want your hook to run
1891
	{
1892
		$special_code = $object->lines[$i]->special_code;
1893
		if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1894
		$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
1895
		$action='';
1896
		$reshook = $hookmanager->executeHooks('pdf_getlinetotalwithtax',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1897
1898
		if(!empty($hookmanager->resPrint)) $result.=$hookmanager->resPrint;
1899
	}
1900
	if (empty($reshook))
1901
	{
1902
		if ($object->lines[$i]->special_code == 3)
1903
    	{
1904
    		$result.=$outputlangs->transnoentities("Option");
1905
    	}
1906
		elseif (empty($hidedetails) || $hidedetails > 1) $result.=price($sign * ($object->lines[$i]->total_ht) + ($object->lines[$i]->total_ht)*($object->lines[$i]->tva_tx)/100, 0, $outputlangs);
1907
	}
1908
	return $result;
1909
}
1910
1911
/**
1912
 *	Return total quantity of products and/or services
1913
 *
1914
 *	@param	Object		$object				Object
1915
 *	@param	string		$type				Type
1916
 *  @param  Translate	$outputlangs		Object langs for output
1917
 * 	@return	integer
1918
 *  @deprecated Not used by Dolibarr core, so will be removed.
1919
 */
1920
function pdf_getTotalQty($object,$type,$outputlangs)
1921
{
1922
	global $hookmanager;
1923
1924
	$total=0;
1925
	$nblignes=count($object->lines);
1926
1927
	// Loop on each lines
1928
	for ($i = 0 ; $i < $nblignes ; $i++)
1929
	{
1930
		if ($object->lines[$i]->special_code != 3)
1931
		{
1932
			if ($type=='all')
1933
			{
1934
				$total += $object->lines[$i]->qty;
1935
			}
1936
			else if ($type==9 && is_object($hookmanager) && (($object->lines[$i]->product_type == 9 && ! empty($object->lines[$i]->special_code)) || ! empty($object->lines[$i]->fk_parent_line)))
1937
			{
1938
				$special_code = $object->lines[$i]->special_code;
1939
				if (! empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
1940
				$parameters = array('i'=>$i,'outputlangs'=>$outputlangs,'hidedetails'=>$hidedetails,'special_code'=>$special_code);
0 ignored issues
show
Bug introduced by
The variable $hidedetails 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...
1941
				$action='';
1942
				$reshook = $hookmanager->executeHooks('pdf_getTotalQty',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
1943
				return $hookmanager->resPrint;
1944
			}
1945
			else if ($type==0 && $object->lines[$i]->product_type == 0)
1946
			{
1947
				$total += $object->lines[$i]->qty;
1948
			}
1949
			else if ($type==1 && $object->lines[$i]->product_type == 1)
1950
			{
1951
				$total += $object->lines[$i]->qty;
1952
			}
1953
		}
1954
	}
1955
1956
	return $total;
1957
}
1958
1959
/**
1960
 * 	Return linked objects to use for document generation.
1961
 *  Warning: To save space, this function returns only one link per link type (all links are concated on same record string). This function is used by pdf_writeLinkedObjects
1962
 *
1963
 * 	@param	object		$object			Object
1964
 * 	@param	Translate	$outputlangs	Object lang for output
1965
 * 	@return	array                       Linked objects
1966
 */
1967
function pdf_getLinkedObjects($object,$outputlangs)
1968
{
1969
	global $hookmanager;
1970
1971
	$linkedobjects=array();
1972
1973
	$object->fetchObjectLinked();
1974
1975
	foreach($object->linkedObjects as $objecttype => $objects)
1976
	{
1977
	    if ($objecttype == 'facture')
1978
	    {
1979
	       // For invoice, we don't want to have a reference line on document. Image we are using recuring invoice, we will have a line longer than document width.
1980
	    }
1981
	    elseif ($objecttype == 'propal' || $objecttype == 'supplier_proposal')
1982
		{
1983
			$outputlangs->load('propal');
1984
1985
			foreach($objects as $elementobject)
1986
			{
1987
				$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal");
1988
				$linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
1989
				$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal");
1990
				$linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date,'day','',$outputlangs);
1991
			}
1992
		}
1993
		else if ($objecttype == 'commande' || $objecttype == 'supplier_order')
1994
		{
1995
			$outputlangs->load('orders');
1996
			foreach($objects as $elementobject)
1997
			{
1998
				$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder");
1999
				$linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref) . ($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : '') . ($elementobject->ref_supplier ? ' ('.$elementobject->ref_supplier.')' : '');
2000
				$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate");
2001
				$linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date,'day','',$outputlangs);
2002
			}
2003
		}
2004
		else if ($objecttype == 'contrat')
2005
		{
2006
			$outputlangs->load('contracts');
2007
			foreach($objects as $elementobject)
2008
			{
2009
				$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract");
2010
				$linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref);
2011
				$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract");
2012
				$linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat,'day','',$outputlangs);
2013
			}
2014
		}
2015
		else if ($objecttype == 'shipping')
2016
		{
2017
			$outputlangs->load('orders');
2018
			$outputlangs->load('sendings');
2019
			foreach($objects as $x => $elementobject)
2020
			{
2021
			    $order=null;
2022
			    // We concat this record info into fields xxx_value. title is overwrote.
2023
			    if (empty($object->linkedObjects['commande']) && $object->element != 'commande')	// There is not already a link to order and object is not the order, so we show also info with order
2024
			    {
2025
			        $elementobject->fetchObjectLinked();
2026
			        if (! empty($elementobject->linkedObjects['commande'])) $order = reset($elementobject->linkedObjects['commande']);
2027
			    }
2028
			    if (! is_object($order))
2029
			    {
2030
			        $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
2031
			        if (! empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'].=' / ';
2032
			        $linkedobjects[$objecttype]['ref_value'].= $outputlangs->transnoentities($elementobject->ref);
2033
			        //$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateShipment");
2034
			        //if (! empty($linkedobjects[$objecttype]['date_value'])) $linkedobjects[$objecttype]['date_value'].=' / ';
2035
			        //$linkedobjects[$objecttype]['date_value'].= dol_print_date($elementobject->date_delivery,'day','',$outputlangs);
2036
			    }
2037
			    else
2038
			    {
2039
			        $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder") . ' / ' . $outputlangs->transnoentities("RefSending");
2040
			        if (empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref) . ($order->ref_client ? ' ('.$order->ref_client.')' : '');
2041
			        $linkedobjects[$objecttype]['ref_value'].= ' / ' . $outputlangs->transnoentities($elementobject->ref);
2042
			        //$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate") . ($elementobject->date_delivery ? ' / ' . $outputlangs->transnoentities("DateShipment") : '');
2043
			        //if (empty($linkedobjects[$objecttype]['date_value'])) $linkedobjects[$objecttype]['date_value'] = dol_print_date($order->date,'day','',$outputlangs);
2044
			        //$linkedobjects[$objecttype]['date_value'].= ($elementobject->date_delivery ? ' / ' . dol_print_date($elementobject->date_delivery,'day','',$outputlangs) : '');
2045
			    }
2046
			}
2047
		}
2048
	}
2049
2050
	// For add external linked objects
2051
	if (is_object($hookmanager))
2052
	{
2053
		$parameters = array('linkedobjects' => $linkedobjects, 'outputlangs'=>$outputlangs);
2054
		$action='';
2055
		$hookmanager->executeHooks('pdf_getLinkedObjects',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
2056
		if (! empty($hookmanager->resArray)) $linkedobjects = $hookmanager->resArray;
2057
	}
2058
2059
	return $linkedobjects;
2060
}
2061
2062
/**
2063
 * Return dimensions to use for images onto PDF checking that width and height are not higher than
2064
 * maximum (16x32 by default).
2065
 *
2066
 * @param	string		$realpath		Full path to photo file to use
2067
 * @return	array						Height and width to use to output image (in pdf user unit, so mm)
2068
 */
2069
function pdf_getSizeForImage($realpath)
2070
{
2071
	global $conf;
2072
2073
	$maxwidth=(empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH);
2074
	$maxheight=(empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT)?32:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_HEIGHT);
2075
	include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
2076
	$tmp=dol_getImageSize($realpath);
2077
	if ($tmp['height'])
2078
	{
2079
		$width=(int) round($maxheight*$tmp['width']/$tmp['height']);	// I try to use maxheight
2080
		if ($width > $maxwidth)	// Pb with maxheight, so i use maxwidth
2081
		{
2082
			$width=$maxwidth;
2083
			$height=(int) round($maxwidth*$tmp['height']/$tmp['width']);
2084
		}
2085
		else	// No pb with maxheight
2086
		{
2087
			$height=$maxheight;
2088
		}
2089
	}
2090
	return array('width'=>$width,'height'=>$height);
0 ignored issues
show
Bug introduced by
The variable $width 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...
Bug introduced by
The variable $height 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...
2091
}
2092
2093