Completed
Branch develop (854a6c)
by
unknown
22:58
created

files.lib.php ➔ dolReplaceRegExInFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 5
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2008-2012  Laurent Destailleur <[email protected]>
3
 * Copyright (C) 2012-2015  Regis Houssin       <[email protected]>
4
 * Copyright (C) 2012-2016  Juanjo Menent       <[email protected]>
5
 * Copyright (C) 2015       Marcos García       <[email protected]>
6
 * Copyright (C) 2016       Raphaël Doursenaud  <[email protected]>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
 * or see http://www.gnu.org/
21
 */
22
23
/**
24
 *  \file		htdocs/core/lib/files.lib.php
25
 *  \brief		Library for file managing functions
26
 */
27
28
/**
29
 * Make a basename working with all page code (default PHP basenamed fails with cyrillic).
30
 * We supose dir separator for input is '/'.
31
 *
32
 * @param	string	$pathfile	String to find basename.
33
 * @return	string				Basename of input
34
 */
35
function dol_basename($pathfile)
36
{
37
    return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/'));
38
}
39
40
/**
41
 *  Scan a directory and return a list of files/directories.
42
 *  Content for string is UTF8 and dir separator is "/".
43
 *
44
 *  @param	string		$path        	Starting path from which to search. This is a full path.
45
 *  @param	string		$types        	Can be "directories", "files", or "all"
46
 *  @param	int			$recursive		Determines whether subdirectories are searched
47
 *  @param	string		$filter        	Regex filter to restrict list. This regex value must be escaped for '/' by doing preg_quote($var,'/'), since this char is used for preg_match function,
48
 *                                      but must not contains the start and end '/'. Filter is checked into basename only.
49
 *  @param	array		$excludefilter  Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). Exclude is checked into fullpath.
50
 *  @param	string		$sortcriteria	Sort criteria ("","fullname","relativename","name","date","size")
51
 *  @param	string		$sortorder		Sort order (SORT_ASC, SORT_DESC)
52
 *	@param	int			$mode			0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only
53
 *  @param	int			$nohook			Disable all hooks
54
 *  @param	string		$relativename	For recursive purpose only. Must be "" at first call.
55
 *  @return	array						Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file',...)
56
 *  @see dol_dir_list_indatabase
57
 */
58
function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter="", $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="")
59
{
60
	global $db, $hookmanager;
61
	global $object;
62
63
	dol_syslog("files.lib.php::dol_dir_list path=".$path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter));
64
	//print 'xxx'."files.lib.php::dol_dir_list path=".$path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter);
65
66
	$loaddate=($mode==1||$mode==2)?true:false;
67
	$loadsize=($mode==1||$mode==3)?true:false;
68
69
	// Clean parameters
70
	$path=preg_replace('/([\\/]+)$/i','',$path);
71
	$newpath=dol_osencode($path);
72
73
	$reshook = 0;
74
	$file_list = array();
75
76
	if (is_object($hookmanager) && ! $nohook)
77
	{
78
	    $hookmanager->resArray=array();
79
80
	    $hookmanager->initHooks(array('fileslib'));
81
82
		$parameters=array(
83
				'path' => $newpath,
84
				'types'=> $types,
85
				'recursive' => $recursive,
86
				'filter' => $filter,
87
				'excludefilter' => $excludefilter,
88
				'sortcriteria' => $sortcriteria,
89
				'sortorder' => $sortorder,
90
				'loaddate' => $loaddate,
91
				'loadsize' => $loadsize,
92
				'mode' => $mode
93
		);
94
		$reshook=$hookmanager->executeHooks('getDirList', $parameters, $object);
95
	}
96
97
	// $hookmanager->resArray may contain array stacked by other modules
98
	if (empty($reshook))
99
	{
100
		if (! is_dir($newpath)) return array();
101
102
		if ($dir = opendir($newpath))
103
		{
104
			$filedate='';
105
			$filesize='';
106
107
			while (false !== ($file = readdir($dir)))        // $file is always a basename (into directory $newpath)
108
			{
109
				if (! utf8_check($file)) $file=utf8_encode($file);	// To be sure data is stored in utf8 in memory
110
111
				$qualified=1;
112
113
				// Define excludefilterarray
114
				$excludefilterarray=array('^\.');
115
				if (is_array($excludefilter))
116
				{
117
					$excludefilterarray=array_merge($excludefilterarray,$excludefilter);
118
				}
119
				else if ($excludefilter) $excludefilterarray[]=$excludefilter;
120
				// Check if file is qualified
121
				foreach($excludefilterarray as $filt)
122
				{
123
					if (preg_match('/'.$filt.'/i',$file)) {
124
						$qualified=0; break;
125
					}
126
				}
127
128
				if ($qualified)
129
				{
130
					$isdir=is_dir(dol_osencode($path."/".$file));
131
					// Check whether this is a file or directory and whether we're interested in that type
132
					if ($isdir && (($types=="directories") || ($types=="all") || $recursive))
133
					{
134
						// Add entry into file_list array
135
						if (($types=="directories") || ($types=="all"))
136
						{
137
							if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file);
138
							if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file);
139
140
							if (! $filter || preg_match('/'.$filter.'/i',$file))	// We do not search key $filter into all $path, only into $file part
141
							{
142
								preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg);
143
								$level1name=(isset($reg[1])?$reg[1]:'');
144
								$file_list[] = array(
145
										"name" => $file,
146
										"path" => $path,
147
										"level1name" => $level1name,
148
										"relativename" => ($relativename?$relativename.'/':'').$file,
149
										"fullname" => $path.'/'.$file,
150
										"date" => $filedate,
151
										"size" => $filesize,
152
										"type" => 'dir'
153
								);
154
							}
155
						}
156
157
						// if we're in a directory and we want recursive behavior, call this function again
158
						if ($recursive)
159
						{
160
							$file_list = array_merge($file_list, dol_dir_list($path."/".$file, $types, $recursive, $filter, $excludefilter, $sortcriteria, $sortorder, $mode, $nohook, ($relativename?$relativename.'/':'').$file));
161
						}
162
					}
163
					else if (! $isdir && (($types == "files") || ($types == "all")))
164
					{
165
						// Add file into file_list array
166
						if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file);
167
						if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file);
168
169
						if (! $filter || preg_match('/'.$filter.'/i',$file))	// We do not search key $filter into $path, only into $file
170
						{
171
							preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg);
172
							$level1name=(isset($reg[1])?$reg[1]:'');
173
							$file_list[] = array(
174
									"name" => $file,
175
									"path" => $path,
176
									"level1name" => $level1name,
177
									"relativename" => ($relativename?$relativename.'/':'').$file,
178
									"fullname" => $path.'/'.$file,
179
									"date" => $filedate,
180
									"size" => $filesize,
181
									"type" => 'file'
182
							);
183
						}
184
					}
185
				}
186
			}
187
			closedir($dir);
188
189
			// Obtain a list of columns
190
			if (! empty($sortcriteria))
191
			{
192
				$myarray=array();
193
				foreach ($file_list as $key => $row)
194
				{
195
					$myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:'');
196
				}
197
				// Sort the data
198
				if ($sortorder) array_multisort($myarray, $sortorder, $file_list);
199
			}
200
		}
201
	}
202
203
	if (is_object($hookmanager) && is_array($hookmanager->resArray)) $file_list = array_merge($file_list, $hookmanager->resArray);
204
205
	return $file_list;
206
}
207
208
209
/**
210
 *  Scan a directory and return a list of files/directories.
211
 *  Content for string is UTF8 and dir separator is "/".
212
 *
213
 *  @param	string		$path        	Starting path from which to search. Example: 'produit/MYPROD'
214
 *  @param	string		$filter        	Regex filter to restrict list. This regex value must be escaped for '/', since this char is used for preg_match function
215
 *  @param	array|null	$excludefilter  Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.'))
216
 *  @param	string		$sortcriteria	Sort criteria ("","fullname","name","date","size")
217
 *  @param	string		$sortorder		Sort order (SORT_ASC, SORT_DESC)
218
 *	@param	int			$mode			0=Return array minimum keys loaded (faster), 1=Force all keys like description
219
 *  @return	array						Array of array('name'=>'xxx','fullname'=>'/abc/xxx','type'=>'dir|file',...)
220
 *  @see dol_dir_list
221
 */
222
function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0)
223
{
224
    global $conf, $db;
225
226
    $sql=" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position";
227
    if ($mode) $sql.=", description";
228
    $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files";
229
    $sql.=" WHERE filepath = '".$db->escape($path)."'";
230
    $sql.=" AND entity = ".$conf->entity;
231
232
    $resql = $db->query($sql);
233
    if ($resql)
234
    {
235
        $file_list=array();
236
        $num = $db->num_rows($resql);
237
        $i = 0;
238
        while ($i < $num)
239
        {
240
            $obj = $db->fetch_object($resql);
241
            if ($obj)
242
            {
243
                preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg);
244
                $level1name=(isset($reg[1])?$reg[1]:'');
245
                $file_list[] = array(
246
                    "rowid" => $obj->rowid,
247
                    "label" => $obj->label,         // md5
248
    				"name" => $obj->filename,
249
    				"path" => DOL_DATA_ROOT.'/'.$obj->filepath,
250
                    "level1name" => $level1name,
251
    				"fullname" => DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,
252
    				"fullpath_orig" => $obj->fullpath_orig,
253
                    "date_c" => $db->jdate($obj->date_c),
254
                    "date_m" => $db->jdate($obj->date_m),
255
    				"type" => 'file',
256
                    "keywords" => $obj->keywords,
257
                    "cover" => $obj->cover,
258
                    "position" => (int) $obj->position,
259
                    "acl" => $obj->acl
260
                );
261
            }
262
            $i++;
263
        }
264
265
        // Obtain a list of columns
266
        if (! empty($sortcriteria))
267
        {
268
            $myarray=array();
269
            foreach ($file_list as $key => $row)
270
            {
271
                $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:'');
272
            }
273
            // Sort the data
274
            if ($sortorder) array_multisort($myarray, $sortorder, $file_list);
275
        }
276
277
        return $file_list;
278
    }
279
    else
280
    {
281
        dol_print_error($db);
282
        return array();
283
    }
284
}
285
286
287
/**
288
 * Fast compare of 2 files identified by their properties ->name, ->date and ->size
289
 *
290
 * @param	string 	$a		File 1
291
 * @param 	string	$b		File 2
292
 * @return 	int				1, 0, 1
293
 */
294
function dol_compare_file($a, $b)
295
{
296
	global $sortorder;
297
	global $sortfield;
298
299
	$sortorder=strtoupper($sortorder);
300
301
	if ($sortorder == 'ASC') { $retup=-1; $retdown=1; }
302
	else { $retup=1; $retdown=-1; }
303
304
	if ($sortfield == 'name')
305
	{
306
		if ($a->name == $b->name) return 0;
307
		return ($a->name < $b->name) ? $retup : $retdown;
308
	}
309
	if ($sortfield == 'date')
310
	{
311
		if ($a->date == $b->date) return 0;
312
		return ($a->date < $b->date) ? $retup : $retdown;
313
	}
314
	if ($sortfield == 'size')
315
	{
316
		if ($a->size == $b->size) return 0;
317
		return ($a->size < $b->size) ? $retup : $retdown;
318
	}
319
}
320
321
322
/**
323
 * Test if filename is a directory
324
 *
325
 * @param	string		$folder     Name of folder
326
 * @return	boolean     			True if it's a directory, False if not found
327
 */
328
function dol_is_dir($folder)
329
{
330
    $newfolder=dol_osencode($folder);
331
    if (is_dir($newfolder)) return true;
332
    else return false;
333
}
334
335
/**
336
 * Return if path is a file
337
 *
338
 * @param   string		$pathoffile		Path of file
339
 * @return  boolean     			    True or false
340
 */
341
function dol_is_file($pathoffile)
342
{
343
    $newpathoffile=dol_osencode($pathoffile);
344
    return is_file($newpathoffile);
345
}
346
347
/**
348
 * Return if path is an URL
349
 *
350
 * @param   string		$url	Url
351
 * @return  boolean      	   	True or false
352
 */
353
function dol_is_url($url)
354
{
355
    $tmpprot=array('file','http','https','ftp','zlib','data','ssh','ssh2','ogg','expect');
356
    foreach($tmpprot as $prot)
357
    {
358
        if (preg_match('/^'.$prot.':/i',$url)) return true;
359
    }
360
    return false;
361
}
362
363
/**
364
 * 	Test if a folder is empty
365
 *
366
 * 	@param	string	$folder		Name of folder
367
 * 	@return boolean				True if dir is empty or non-existing, False if it contains files
368
 */
369
function dol_dir_is_emtpy($folder)
370
{
371
	$newfolder=dol_osencode($folder);
372
	if (is_dir($newfolder))
373
	{
374
		$handle = opendir($newfolder);
375
        $folder_content = '';
376
		while ((gettype($name = readdir($handle)) != "boolean"))
377
		{
378
			$name_array[] = $name;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$name_array was never initialized. Although not strictly required by PHP, it is generally a good practice to add $name_array = array(); before regardless.

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

Let’s take a look at an example:

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

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

    // do something with $myArray
}

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

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

Loading history...
379
		}
380
		foreach($name_array as $temp) $folder_content .= $temp;
0 ignored issues
show
Bug introduced by
The variable $name_array does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
381
382
        closedir($handle);
383
384
		if ($folder_content == "...") return true;
385
		else return false;
386
	}
387
	else
388
	return true; // Dir does not exists
389
}
390
391
/**
392
 * 	Count number of lines in a file
393
 *
394
 * 	@param	string	$file		Filename
395
 * 	@return int					<0 if KO, Number of lines in files if OK
396
 */
397
function dol_count_nb_of_line($file)
398
{
399
	$nb=0;
400
401
	$newfile=dol_osencode($file);
402
	//print 'x'.$file;
403
	$fp=fopen($newfile,'r');
404
	if ($fp)
405
	{
406
		while (!feof($fp))
407
		{
408
			$line=fgets($fp);
409
            // We increase count only if read was success. We need test because feof return true only after fgets so we do n+1 fgets for a file with n lines.
410
			if (! $line === false) $nb++;
411
		}
412
		fclose($fp);
413
	}
414
	else
415
	{
416
		$nb=-1;
417
	}
418
419
	return $nb;
420
}
421
422
423
/**
424
 * Return size of a file
425
 *
426
 * @param 	string		$pathoffile		Path of file
427
 * @return 	integer						File size
428
 */
429
function dol_filesize($pathoffile)
430
{
431
	$newpathoffile=dol_osencode($pathoffile);
432
	return filesize($newpathoffile);
433
}
434
435
/**
436
 * Return time of a file
437
 *
438
 * @param 	string		$pathoffile		Path of file
439
 * @return 	int					Time of file
440
 */
441
function dol_filemtime($pathoffile)
442
{
443
	$newpathoffile=dol_osencode($pathoffile);
444
	return @filemtime($newpathoffile); // @Is to avoid errors if files does not exists
445
}
446
447
/**
448
 * Make replacement of strings into a file.
449
 *
450
 * @param	string	$srcfile			Source file (can't be a directory)
451
 * @param	array	$arrayreplacement	Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...)
452
 * @param	string	$destfile			Destination file (can't be a directory). If empty, will be same than source file.
453
 * @param	int		$newmask			Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666'
454
 * @param	int		$indexdatabase		Index new file into database.
455
 * @return	int							<0 if error, 0 if nothing done (dest file already exists), >0 if OK
456
 * @see		dolCopyr dolReplaceRegExInFile
457
 */
458
function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
459
{
460
    global $conf;
461
462
    dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase);
463
464
    if (empty($srcfile)) return -1;
465
    if (empty($destfile)) $destfile=$srcfile;
466
467
    $destexists=dol_is_file($destfile);
468
    if (($destfile != $srcfile) && $destexists) return 0;
469
470
    $tmpdestfile=$destfile.'.tmp';
471
472
    $newpathofsrcfile=dol_osencode($srcfile);
473
    $newpathoftmpdestfile=dol_osencode($tmpdestfile);
474
    $newpathofdestfile=dol_osencode($destfile);
475
    $newdirdestfile=dirname($newpathofdestfile);
476
477
    if ($destexists && ! is_writable($newpathofdestfile))
478
    {
479
        dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to overwrite target file", LOG_WARNING);
480
        return -1;
481
    }
482
    if (! is_writable($newdirdestfile))
483
    {
484
        dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING);
485
        return -2;
486
    }
487
488
    dol_delete_file($tmpdestfile);
489
490
    // Create $newpathoftmpdestfile from $newpathofsrcfile
491
    $content=file_get_contents($newpathofsrcfile, 'r');
492
493
    $content = make_substitutions($content, $arrayreplacement, null);
494
495
    file_put_contents($newpathoftmpdestfile, $content);
496
    @chmod($newpathoftmpdestfile, octdec($newmask));
497
498
    // Rename
499
    $result=dol_move($newpathoftmpdestfile, $newpathofdestfile, $newmask, (($destfile == $srcfile)?1:0), 0, $indexdatabase);
500
    if (! $result)
501
    {
502
        dol_syslog("files.lib.php::dolReplaceInFile failed to move tmp file to final dest", LOG_WARNING);
503
        return -3;
504
    }
505
    if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
506
    if (empty($newmask))	// This should no happen
507
    {
508
        dol_syslog("Warning: dolReplaceInFile called with empty value for newmask and no default value defined", LOG_WARNING);
509
        $newmask='0664';
510
    }
511
512
    @chmod($newpathofdestfile, octdec($newmask));
513
514
    return 1;
515
}
516
517
/**
518
 * Make replacement of strings into a file.
519
 *
520
 * @param	string	$srcfile			Source file (can't be a directory)
521
 * @param	array	$arrayreplacement	Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...)
522
 * @param	string	$destfile			Destination file (can't be a directory). If empty, will be same than source file.
523
 * @param	int		$newmask			Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666'
524
 * @param	int		$indexdatabase		Index new file into database.
525
 * @return	int							<0 if error, 0 if nothing done (dest file already exists), >0 if OK
526
 * @see		dolCopyr dolReplaceInFile
527
 */
528
function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
529
{
530
	// TODO
531
532
}
533
534
/**
535
 * Copy a file to another file.
536
 *
537
 * @param	string	$srcfile			Source file (can't be a directory)
538
 * @param	string	$destfile			Destination file (can't be a directory)
539
 * @param	int		$newmask			Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666'
540
 * @param 	int		$overwriteifexists	Overwrite file if exists (1 by default)
541
 * @return	int							<0 if error, 0 if nothing done (dest file already exists and overwriteifexists=0), >0 if OK
542
 * @see		dolCopyr
543
 */
544
function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
545
{
546
	global $conf;
547
548
	dol_syslog("files.lib.php::dol_copy srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwriteifexists=".$overwriteifexists);
549
550
	if (empty($srcfile) || empty($destfile)) return -1;
551
552
	$destexists=dol_is_file($destfile);
553
	if (! $overwriteifexists && $destexists) return 0;
554
555
	$newpathofsrcfile=dol_osencode($srcfile);
556
    $newpathofdestfile=dol_osencode($destfile);
557
    $newdirdestfile=dirname($newpathofdestfile);
558
559
    if ($destexists && ! is_writable($newpathofdestfile))
560
    {
561
        dol_syslog("files.lib.php::dol_copy failed Permission denied to overwrite target file", LOG_WARNING);
562
        return -1;
563
    }
564
    if (! is_writable($newdirdestfile))
565
    {
566
        dol_syslog("files.lib.php::dol_copy failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING);
567
        return -2;
568
    }
569
    // Copy with overwriting if exists
570
    $result=@copy($newpathofsrcfile, $newpathofdestfile);
571
	//$result=copy($newpathofsrcfile, $newpathofdestfile);	// To see errors, remove @
572
	if (! $result)
573
	{
574
	    dol_syslog("files.lib.php::dol_copy failed to copy", LOG_WARNING);
575
	    return -3;
576
	}
577
	if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
578
	if (empty($newmask))	// This should no happen
579
	{
580
		dol_syslog("Warning: dol_copy called with empty value for newmask and no default value defined", LOG_WARNING);
581
		$newmask='0664';
582
	}
583
584
	@chmod($newpathofdestfile, octdec($newmask));
585
586
	return 1;
587
}
588
589
/**
590
 * Copy a dir to another dir.
591
 *
592
 * @param	string	$srcfile			Source file (a directory)
593
 * @param	string	$destfile			Destination file (a directory)
594
 * @param	int		$newmask			Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666'
595
 * @param 	int		$overwriteifexists	Overwrite file if exists (1 by default)
596
 * @param	array	$arrayreplacement	Array to use to replace filenames with another one during the copy (works only on file names, not on directory names).
597
 * @return	int							<0 if error, 0 if nothing done (all files already exists and overwriteifexists=0), >0 if OK
598
 * @see		dol_copy
599
 */
600
function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null)
601
{
602
	global $conf;
603
604
	$result=0;
605
606
	dol_syslog("files.lib.php::dolCopyDir srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwriteifexists=".$overwriteifexists);
607
608
	if (empty($srcfile) || empty($destfile)) return -1;
609
610
	$destexists=dol_is_dir($destfile);
611
	//if (! $overwriteifexists && $destexists) return 0;	// The overwriteifexists is for files only, so propagated to dol_copy only.
612
613
    if (! $destexists)
614
    {
615
        // We must set mask just before creating dir, becaause it can be set differently by dol_copy
616
        umask(0);
617
        $dirmaskdec=octdec($newmask);
618
        if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK);
619
        $dirmaskdec |= octdec('0200');  // Set w bit required to be able to create content for recursive subdirs files
620
        dol_mkdir($destfile, '', decoct($dirmaskdec));
621
    }
622
623
	$ossrcfile=dol_osencode($srcfile);
624
	$osdestfile=dol_osencode($destfile);
625
626
    // Recursive function to copy all subdirectories and contents:
627
	if (is_dir($ossrcfile))
628
	{
629
        $dir_handle=opendir($ossrcfile);
630
        while ($file=readdir($dir_handle))
631
        {
632
            if ($file!="." && $file!="..")
633
            {
634
                if (is_dir($ossrcfile."/".$file))
635
                {
636
                    //var_dump("xxx dolCopyDir $srcfile/$file, $destfile/$file, $newmask, $overwriteifexists");
637
                    $tmpresult=dolCopyDir($srcfile."/".$file, $destfile."/".$file, $newmask, $overwriteifexists, $arrayreplacement);
638
                }
639
                else
640
				{
641
					$newfile = $file;
642
					// Replace destination filename with a new one
643
					if (is_array($arrayreplacement))
644
					{
645
						foreach($arrayreplacement as $key => $val)
646
						{
647
							$newfile = str_replace($key, $val, $newfile);
648
						}
649
					}
650
                    $tmpresult=dol_copy($srcfile."/".$file, $destfile."/".$newfile, $newmask, $overwriteifexists);
651
                }
652
                // Set result
653
                if ($result > 0 && $tmpresult >= 0)
654
                {
655
                    // Do nothing, so we don't set result to 0 if tmpresult is 0 and result was success in a previous pass
656
                }
657
                else
658
                {
659
                    $result=$tmpresult;
660
                }
661
                if ($result < 0) break;
662
663
            }
664
        }
665
        closedir($dir_handle);
666
    }
667
    else
668
	{
669
		// Source directory does not exists
670
        $result = -2;
671
    }
672
673
    return $result;
674
}
675
676
677
/**
678
 * Move a file into another name.
679
 * Note:
680
 *  - This function differs from dol_move_uploaded_file, because it can be called in any context.
681
 *  - Database of files is updated.
682
 *  - Test on antivirus is done only if param testvirus is provided and an antivirus was set.
683
 *
684
 * @param	string  $srcfile            Source file (can't be a directory. use native php @rename() to move a directory)
685
 * @param   string	$destfile           Destination file (can't be a directory. use native php @rename() to move a directory)
686
 * @param   integer	$newmask            Mask in octal string for new file (0 by default means $conf->global->MAIN_UMASK)
687
 * @param   int		$overwriteifexists  Overwrite file if exists (1 by default)
688
 * @param   int     $testvirus          Do an antivirus test. Move is canceled if a virus is found.
689
 * @param	int		$indexdatabase		Index new file into database.
690
 * @return  boolean 		            True if OK, false if KO
691
 * @see dol_move_uploaded_file
692
 */
693
function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1)
694
{
695
    global $user, $db, $conf;
696
    $result=false;
697
698
    dol_syslog("files.lib.php::dol_move srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwritifexists=".$overwriteifexists);
699
    $srcexists=dol_is_file($srcfile);
700
    $destexists=dol_is_file($destfile);
701
702
    if (! $srcexists)
703
    {
704
        dol_syslog("files.lib.php::dol_move srcfile does not exists. we ignore the move request.");
705
        return false;
706
    }
707
708
    if ($overwriteifexists || ! $destexists)
709
    {
710
        $newpathofsrcfile=dol_osencode($srcfile);
711
        $newpathofdestfile=dol_osencode($destfile);
712
713
        // Check virus
714
        $testvirusarray=array();
715
        if ($testvirus)
716
        {
717
            $testvirusarray=dolCheckVirus($newpathofsrcfile);
718
            if (count($testvirusarray))
719
            {
720
                dol_syslog("files.lib.php::dol_move canceled because a virus was found into source file. we ignore the move request.", LOG_WARNING);
721
                return false;
722
            }
723
        }
724
725
        $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @
726
        if (! $result)
727
        {
728
        	if ($destexists)
729
        	{
730
        		dol_syslog("files.lib.php::dol_move Failed. We try to delete target first and move after.", LOG_WARNING);
731
        		// We force delete and try again. Rename function sometimes fails to replace dest file with some windows NTFS partitions.
732
        		dol_delete_file($destfile);
733
        		$result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @
734
        	}
735
        	else dol_syslog("files.lib.php::dol_move Failed.", LOG_WARNING);
736
        }
737
738
        // Move ok
739
        if ($result && $indexdatabase)
740
        {
741
            // Rename entry into ecm database
742
            $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile);
743
            $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile);
744
            if (! preg_match('/(\/temp\/|\/thumbs|\.meta$)/', $rel_filetorenameafter))     // If not a tmp file
745
            {
746
                $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore);
747
                $rel_filetorenameafter = preg_replace('/^[\\/]/', '', $rel_filetorenameafter);
748
                //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter);
749
750
                dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG);
751
                include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
752
753
                $ecmfiletarget=new EcmFiles($db);
754
                $resultecmtarget = $ecmfiletarget->fetch(0, '', $rel_filetorenameafter);
755
                if ($resultecmtarget > 0)   // An entry for target name already exists for target, we delete it, a new one will be created.
756
                {
757
                    $ecmfiletarget->delete($user);
758
                }
759
760
                $ecmfile=new EcmFiles($db);
761
                $resultecm = $ecmfile->fetch(0, '', $rel_filetorenamebefore);
762
                if ($resultecm > 0)   // If an entry was found for src file, we use it to move entry
763
                {
764
                    $filename = basename($rel_filetorenameafter);
765
                    $rel_dir = dirname($rel_filetorenameafter);
766
                    $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
767
                    $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
768
769
                    $ecmfile->filepath = $rel_dir;
770
                    $ecmfile->filename = $filename;
771
                    $resultecm = $ecmfile->update($user);
772
                }
773
                elseif ($resultecm == 0)   // If no entry were found for src files, create/update target file
774
                {
775
                    $filename = basename($rel_filetorenameafter);
776
                    $rel_dir = dirname($rel_filetorenameafter);
777
                    $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
778
                    $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
779
780
                    $ecmfile->filepath = $rel_dir;
781
                    $ecmfile->filename = $filename;
782
                    $ecmfile->label = md5_file(dol_osencode($destfile));        // $destfile is a full path to file
783
                    $ecmfile->fullpath_orig = $srcfile;
784
                    $ecmfile->gen_or_uploaded = 'unknown';
785
                    $ecmfile->description = '';    // indexed content
786
                    $ecmfile->keyword = '';        // keyword content
787
                    $resultecm = $ecmfile->create($user);
788
                    if ($resultecm < 0)
789
                    {
790
                        setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
791
                    }
792
                }
793
                elseif ($resultecm < 0)
794
                {
795
                    setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
796
                }
797
798
                if ($resultecm > 0) $result=true;
799
                else $result = false;
800
            }
801
        }
802
803
        if (empty($newmask)) $newmask=empty($conf->global->MAIN_UMASK)?'0755':$conf->global->MAIN_UMASK;
804
        $newmaskdec=octdec($newmask);
805
        // Currently method is restricted to files (dol_delete_files previously used is for files, and mask usage if for files too)
806
        // to allow mask usage for dir, we shoul introduce a new param "isdir" to 1 to complete newmask like this
807
        // if ($isdir) $newmaskdec |= octdec('0111');  // Set x bit required for directories
808
        @chmod($newpathofdestfile, $newmaskdec);
809
    }
810
811
    return $result;
812
}
813
814
/**
815
 *	Unescape a file submitted by upload.
816
 *  PHP escape char " (%22) or char ' (%27) into $FILES.
817
 *
818
 *	@param	string	$filename		Filename
819
 *	@return	string					Filename sanitized
820
 */
821
function dol_unescapefile($filename)
822
{
823
	// Remove path information and dots around the filename, to prevent uploading
824
	// into different directories or replacing hidden system files.
825
	// Also remove control characters and spaces (\x00..\x20) around the filename:
826
	return trim(basename($filename), ".\x00..\x20");
827
}
828
829
830
/**
831
 * Check virus into a file
832
 *
833
 * @param   string      $src_file       Source file to check
834
 * @return  array                       Array of errors or empty array if not virus found
835
 */
836
function dolCheckVirus($src_file)
837
{
838
    global $conf;
839
840
    if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND))
841
    {
842
        if (! class_exists('AntiVir')) {
843
            require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php';
844
        }
845
        $antivir=new AntiVir($db);
0 ignored issues
show
Bug introduced by
The variable $db 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...
846
        $result = $antivir->dol_avscan_file($src_file);
847
        if ($result < 0)	// If virus or error, we stop here
848
        {
849
            $reterrors=$antivir->errors;
850
            return $reterrors;
851
        }
852
    }
853
    return array();
854
}
855
856
857
/**
858
 *	Make control on an uploaded file from an GUI page and move it to final destination.
859
 * 	If there is errors (virus found, antivir in error, bad filename), file is not moved.
860
 *  Note:
861
 *  - This function can be used only into a HTML page context. Use dol_move if you are outside.
862
 *  - Test on antivirus is always done (if antivirus set).
863
 *  - Database of files is NOT updated.
864
 *
865
 *	@param	string	$src_file			Source full path filename ($_FILES['field']['tmp_name'])
866
 *	@param	string	$dest_file			Target full path filename  ($_FILES['field']['name'])
867
 * 	@param	int		$allowoverwrite		1=Overwrite target file if it already exists
868
 * 	@param	int		$disablevirusscan	1=Disable virus scan
869
 * 	@param	integer	$uploaderrorcode	Value of PHP upload error code ($_FILES['field']['error'])
870
 * 	@param	int		$nohook				Disable all hooks
871
 * 	@param	string	$varfiles			_FILES var name
872
 *	@return int       			  		>0 if OK, <0 or string if KO
873
 *  @see    dol_move
874
 */
875
function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile')
876
{
877
	global $conf, $db, $user, $langs;
878
	global $object, $hookmanager;
879
880
	$reshook=0;
881
	$file_name = $dest_file;
882
883
	if (empty($nohook))
884
	{
885
		$reshook=$hookmanager->initHooks(array('fileslib'));
886
887
		$parameters=array('dest_file' => $dest_file, 'src_file' => $src_file, 'file_name' => $file_name, 'varfiles' => $varfiles, 'allowoverwrite' => $allowoverwrite);
888
		$reshook=$hookmanager->executeHooks('moveUploadedFile', $parameters, $object);
889
	}
890
891
	if (empty($reshook))
892
	{
893
    	// If an upload error has been reported
894
    	if ($uploaderrorcode)
895
    	{
896
    	    switch($uploaderrorcode)
897
    	    {
898
    	        case UPLOAD_ERR_INI_SIZE:	// 1
899
    	            return 'ErrorFileSizeTooLarge';
900
    	            break;
901
    	        case UPLOAD_ERR_FORM_SIZE:	// 2
902
    	            return 'ErrorFileSizeTooLarge';
903
    	            break;
904
    	        case UPLOAD_ERR_PARTIAL:	// 3
905
    	            return 'ErrorPartialFile';
906
    	            break;
907
    	        case UPLOAD_ERR_NO_TMP_DIR:	//
908
    	            return 'ErrorNoTmpDir';
909
    	            break;
910
    	        case UPLOAD_ERR_CANT_WRITE:
911
    	            return 'ErrorFailedToWriteInDir';
912
    	            break;
913
    	        case UPLOAD_ERR_EXTENSION:
914
    	            return 'ErrorUploadBlockedByAddon';
915
    	            break;
916
    	        default:
917
    	            break;
918
    	    }
919
    	}
920
921
    	// If we need to make a virus scan
922
    	if (empty($disablevirusscan) && file_exists($src_file))
923
    	{
924
    	    $checkvirusarray=dolCheckVirus($src_file);
925
    	    if (count($checkvirusarray))
926
    	    {
927
    	       dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: result='.$result.' errors='.join(',',$checkvirusarray), LOG_WARNING);
0 ignored issues
show
Bug introduced by
The variable $result 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...
928
    	       return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray);
929
    	    }
930
    	}
931
932
    	// Security:
933
    	// Disallow file with some extensions. We rename them.
934
    	// Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
935
    	if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED))
936
    	{
937
    	    $file_name.= '.noexe';
938
    	}
939
940
    	// Security:
941
    	// We refuse cache files/dirs, upload using .. and pipes into filenames.
942
    	if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file))
943
    	{
944
    	    dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
945
    	    return -1;
946
    	}
947
948
    	// Security:
949
    	// On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers.
950
    	if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file))
951
    	{
952
    	    dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
953
    	    return -2;
954
    	}
955
	}
956
957
	if ($reshook < 0)	// At least one blocking error returned by one hook
958
	{
959
		$errmsg = join(',', $hookmanager->errors);
960
		if (empty($errmsg)) $errmsg = 'ErrorReturnedBySomeHooks';	// Should not occurs. Added if hook is bugged and does not set ->errors when there is error.
961
		return $errmsg;
962
	}
963
	elseif (empty($reshook))
964
	{
965
		// The file functions must be in OS filesystem encoding.
966
		$src_file_osencoded=dol_osencode($src_file);
967
		$file_name_osencoded=dol_osencode($file_name);
968
969
		// Check if destination dir is writable
970
		// TODO
971
972
		// Check if destination file already exists
973
		if (! $allowoverwrite)
974
		{
975
			if (file_exists($file_name_osencoded))
976
			{
977
				dol_syslog("Files.lib::dol_move_uploaded_file File ".$file_name." already exists. Return 'ErrorFileAlreadyExists'", LOG_WARNING);
978
				return 'ErrorFileAlreadyExists';
979
			}
980
		}
981
982
		// Move file
983
		$return=move_uploaded_file($src_file_osencoded, $file_name_osencoded);
984
		if ($return)
985
		{
986
			if (! empty($conf->global->MAIN_UMASK)) @chmod($file_name_osencoded, octdec($conf->global->MAIN_UMASK));
987
			dol_syslog("Files.lib::dol_move_uploaded_file Success to move ".$src_file." to ".$file_name." - Umask=".$conf->global->MAIN_UMASK, LOG_DEBUG);
988
			return 1;	// Success
989
		}
990
		else
991
		{
992
			dol_syslog("Files.lib::dol_move_uploaded_file Failed to move ".$src_file." to ".$file_name, LOG_ERR);
993
			return -3;	// Unknown error
994
		}
995
	}
996
997
	return 1;	// Success
998
}
999
1000
/**
1001
 *  Remove a file or several files with a mask
1002
 *
1003
 *  @param	string	$file           File to delete or mask of files to delete
1004
 *  @param  int		$disableglob    Disable usage of glob like * so function is an exact delete function that will return error if no file found
1005
 *  @param  int		$nophperrors    Disable all PHP output errors
1006
 *  @param	int		$nohook			Disable all hooks
1007
 *  @param	object	$object			Current object in use
1008
 *  @return boolean         		True if no error (file is deleted or if glob is used and there's nothing to delete), False if error
1009
 *  @see dol_delete_dir
1010
 */
1011
function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=null)
0 ignored issues
show
Coding Style introduced by
dol_delete_file uses the super-global variable $_GET which is generally not recommended.

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

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

// Better
class Router
{
    private $host;

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

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

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

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1012
{
1013
	global $db, $conf, $user, $langs;
1014
	global $hookmanager;
1015
1016
	$langs->load("other");
1017
	$langs->load("errors");
1018
1019
	dol_syslog("dol_delete_file file=".$file." disableglob=".$disableglob." nophperrors=".$nophperrors." nohook=".$nohook);
1020
1021
	// Security:
1022
	// We refuse transversal using .. and pipes into filenames.
1023
	if (preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file))
1024
	{
1025
        dol_syslog("Refused to delete file ".$file, LOG_WARNING);
1026
	    return False;
1027
	}
1028
1029
	if (empty($nohook))
1030
	{
1031
		$hookmanager->initHooks(array('fileslib'));
1032
1033
		$parameters=array(
1034
				'GET' => $_GET,
1035
				'file' => $file,
1036
				'disableglob'=> $disableglob,
1037
				'nophperrors' => $nophperrors
1038
		);
1039
		$reshook=$hookmanager->executeHooks('deleteFile', $parameters, $object);
1040
	}
1041
1042
	if (empty($nohook) && $reshook != 0) // reshook = 0 to do standard actions, 1 = ok, -1 = ko
1043
	{
1044
		if ($reshook < 0) return false;
0 ignored issues
show
Bug introduced by
The variable $reshook 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...
1045
		return true;
1046
	}
1047
	else
1048
	{
1049
		$error=0;
1050
1051
		//print "x".$file." ".$disableglob;exit;
1052
		$file_osencoded=dol_osencode($file);    // New filename encoded in OS filesystem encoding charset
1053
		if (empty($disableglob) && ! empty($file_osencoded))
1054
		{
1055
			$ok=true;
1056
			$globencoded=str_replace('[','\[',$file_osencoded);
1057
			$globencoded=str_replace(']','\]',$globencoded);
1058
			$listofdir=glob($globencoded);
1059
			if (! empty($listofdir) && is_array($listofdir))
1060
			{
1061
				foreach ($listofdir as $filename)
1062
				{
1063
					if ($nophperrors) $ok=@unlink($filename);
1064
					else $ok=unlink($filename);
1065
					if ($ok)
1066
					{
1067
					    dol_syslog("Removed file ".$filename, LOG_DEBUG);
1068
1069
	                    // Delete entry into ecm database
1070
    				    $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename);
1071
    				    if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete))     // If not a tmp file
1072
    				    {
1073
    				        $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete);
1074
1075
    				        dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG);
1076
        				    include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1077
        				    $ecmfile=new EcmFiles($db);
1078
        				    $result = $ecmfile->fetch(0, '', $rel_filetodelete);
1079
        				    if ($result >= 0 && $ecmfile->id > 0)
1080
        				    {
1081
        				        $result = $ecmfile->delete($user);
1082
        				    }
1083
        				    if ($result < 0)
1084
        				    {
1085
        				        setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
1086
        				    }
1087
    				    }
1088
					}
1089
					else dol_syslog("Failed to remove file ".$filename, LOG_WARNING);
1090
					// TODO Failure to remove can be because file was already removed or because of permission
1091
					// If error because of not exists, we must should return true and we should return false if this is a permission problem
1092
				}
1093
			}
1094
			else dol_syslog("No files to delete found", LOG_DEBUG);
1095
		}
1096
		else
1097
		{
1098
			$ok=false;
1099
			if ($nophperrors) $ok=@unlink($file_osencoded);
1100
			else $ok=unlink($file_osencoded);
1101
			if ($ok) dol_syslog("Removed file ".$file_osencoded, LOG_DEBUG);
1102
			else dol_syslog("Failed to remove file ".$file_osencoded, LOG_WARNING);
1103
		}
1104
1105
		return $ok;
1106
	}
1107
}
1108
1109
/**
1110
 *  Remove a directory (not recursive, so content must be empty).
1111
 *  If directory is not empty, return false
1112
 *
1113
 *  @param	string	$dir            Directory to delete
1114
 *  @param  int		$nophperrors    Disable all PHP output errors
1115
 *  @return boolean         		True if success, false if error
1116
 *  @see dol_delete_file
1117
 */
1118
function dol_delete_dir($dir,$nophperrors=0)
1119
{
1120
	// Security:
1121
	// We refuse transversal using .. and pipes into filenames.
1122
	if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir))
1123
	{
1124
        dol_syslog("Refused to delete dir ".$dir, LOG_WARNING);
1125
	    return False;
1126
	}
1127
1128
    $dir_osencoded=dol_osencode($dir);
1129
    return ($nophperrors?@rmdir($dir_osencoded):rmdir($dir_osencoded));
1130
}
1131
1132
/**
1133
 *  Remove a directory $dir and its subdirectories (or only files and subdirectories)
1134
 *
1135
 *  @param	string	$dir            Dir to delete
1136
 *  @param  int		$count          Counter to count nb of elements found to delete
1137
 *  @param  int		$nophperrors    Disable all PHP output errors
1138
 *  @param	int		$onlysub		Delete only files and subdir, not main directory
1139
 *  @param  int		$countdeleted   Counter to count nb of elements found really deleted
1140
 *  @return int             		Number of files and directory we try to remove. NB really removed is returned into $countdeleted.
1141
 */
1142
function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
1143
{
1144
    dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir,LOG_DEBUG);
1145
    if (dol_is_dir($dir))
1146
    {
1147
        $dir_osencoded=dol_osencode($dir);
1148
        if ($handle = opendir("$dir_osencoded"))
1149
        {
1150
            while (false !== ($item = readdir($handle)))
1151
            {
1152
                if (! utf8_check($item)) $item=utf8_encode($item);  // should be useless
1153
1154
                if ($item != "." && $item != "..")
1155
                {
1156
                    if (is_dir(dol_osencode("$dir/$item")))
1157
                    {
1158
                        $count=dol_delete_dir_recursive("$dir/$item", $count, $nophperrors, 0, $countdeleted);
1159
                    }
1160
                    else
1161
                    {
1162
                        $result=dol_delete_file("$dir/$item", 1, $nophperrors);
1163
                        $count++;
1164
                        if ($result) $countdeleted++;
1165
                    }
1166
                }
1167
            }
1168
            closedir($handle);
1169
1170
            if (empty($onlysub))
1171
            {
1172
	            $result=dol_delete_dir($dir, $nophperrors);
1173
	            $count++;
1174
    	        if ($result) $countdeleted++;
1175
            }
1176
        }
1177
    }
1178
1179
    return $count;
1180
}
1181
1182
1183
/**
1184
 *  Delete all preview files linked to object instance
1185
 *
1186
 *  @param	object	$object		Object to clean
1187
 *  @return	int					0 if error, 1 if OK
1188
 */
1189
function dol_delete_preview($object)
1190
{
1191
	global $langs,$conf;
1192
1193
	// Define parent dir of elements
1194
	$element = $object->element;
1195
1196
    if ($object->element == 'order_supplier')		$dir = $conf->fournisseur->dir_output.'/commande';
1197
    elseif ($object->element == 'invoice_supplier')	$dir = $conf->fournisseur->dir_output.'/facture';
1198
    elseif ($object->element == 'project')			$dir = $conf->projet->dir_output;
1199
    elseif ($object->element == 'shipping')			$dir = $conf->expedition->dir_output.'/sending';
1200
    elseif ($object->element == 'delivery')			$dir = $conf->expedition->dir_output.'/receipt';
1201
    elseif ($object->element == 'fichinter')		$dir = $conf->ficheinter->dir_output;
1202
    else $dir=empty($conf->$element->dir_output)?'':$conf->$element->dir_output;
1203
1204
    if (empty($dir)) return 'ErrorObjectNoSupportedByFunction';
1205
1206
	$refsan = dol_sanitizeFileName($object->ref);
1207
	$dir = $dir . "/" . $refsan ;
1208
	$file = $dir . "/" . $refsan . ".pdf.png";
1209
	$multiple = $file . ".";
1210
1211
	if (file_exists($file) && is_writable($file))
1212
	{
1213
		if (! dol_delete_file($file,1))
1214
		{
1215
			$object->error=$langs->trans("ErrorFailedToDeleteFile",$file);
1216
			return 0;
1217
		}
1218
	}
1219
	else
1220
	{
1221
		for ($i = 0; $i < 20; $i++)
1222
		{
1223
			$preview = $multiple.$i;
1224
1225
			if (file_exists($preview) && is_writable($preview))
1226
			{
1227
				if ( ! dol_delete_file($preview,1) )
1228
				{
1229
					$object->error=$langs->trans("ErrorFailedToOpenFile",$preview);
1230
					return 0;
1231
				}
1232
			}
1233
		}
1234
	}
1235
1236
	return 1;
1237
}
1238
1239
/**
1240
 *	Create a meta file with document file into same directory.
1241
 *	This should allow "grep" search.
1242
 *  This feature is enabled only if option MAIN_DOC_CREATE_METAFILE is set.
1243
 *
1244
 *	@param	CommonObject	$object		Object
1245
 *	@return	int					0 if we did nothing, >0 success, <0 error
1246
 */
1247
function dol_meta_create($object)
1248
{
1249
	global $conf;
1250
1251
	if (empty($conf->global->MAIN_DOC_CREATE_METAFILE)) return 0;	// By default, no metafile.
1252
1253
	// Define parent dir of elements
1254
	$element=$object->element;
1255
1256
	if ($object->element == 'order_supplier')		$dir = $conf->fournisseur->dir_output.'/commande';
1257
	elseif ($object->element == 'invoice_supplier')	$dir = $conf->fournisseur->dir_output.'/facture';
1258
	elseif ($object->element == 'project')			$dir = $conf->projet->dir_output;
1259
	elseif ($object->element == 'shipping')			$dir = $conf->expedition->dir_output.'/sending';
1260
	elseif ($object->element == 'delivery')			$dir = $conf->expedition->dir_output.'/receipt';
1261
	elseif ($object->element == 'fichinter')		$dir = $conf->ficheinter->dir_output;
1262
	else $dir=empty($conf->$element->dir_output)?'':$conf->$element->dir_output;
1263
1264
	if ($dir)
1265
	{
1266
		$object->fetch_thirdparty();
1267
1268
		$facref = dol_sanitizeFileName($object->ref);
1269
		$dir = $dir . "/" . $facref;
1270
		$file = $dir . "/" . $facref . ".meta";
1271
1272
		if (! is_dir($dir))
1273
		{
1274
			dol_mkdir($dir);
1275
		}
1276
1277
		if (is_dir($dir))
1278
		{
1279
			$nblignes = count($object->lines);
1280
			$client = $object->thirdparty->name . " " . $object->thirdparty->address . " " . $object->thirdparty->zip . " " . $object->thirdparty->town;
1281
			$meta = "REFERENCE=\"" . $object->ref . "\"
1282
			DATE=\"" . dol_print_date($object->date,'') . "\"
1283
			NB_ITEMS=\"" . $nblignes . "\"
1284
			CLIENT=\"" . $client . "\"
1285
			TOTAL_HT=\"" . $object->total_ht . "\"
1286
			TOTAL_TTC=\"" . $object->total_ttc . "\"\n";
1287
1288
			for ($i = 0 ; $i < $nblignes ; $i++)
1289
			{
1290
				//Pour les articles
1291
				$meta .= "ITEM_" . $i . "_QUANTITY=\"" . $object->lines[$i]->qty . "\"
1292
				ITEM_" . $i . "_TOTAL_HT=\"" . $object->lines[$i]->total_ht . "\"
1293
				ITEM_" . $i . "_TVA=\"" .$object->lines[$i]->tva_tx . "\"
1294
				ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n","",nl2br($object->lines[$i]->desc)) . "\"
1295
				";
1296
			}
1297
		}
1298
1299
		$fp = fopen($file,"w");
1300
		fputs($fp,$meta);
0 ignored issues
show
Bug introduced by
The variable $meta 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...
1301
		fclose($fp);
1302
		if (! empty($conf->global->MAIN_UMASK))
1303
		@chmod($file, octdec($conf->global->MAIN_UMASK));
1304
1305
		return 1;
1306
	}
1307
1308
	return 0;
1309
}
1310
1311
1312
1313
/**
1314
 * Scan a directory and init $_SESSION to manage uploaded files with list of all found files.
1315
 * Note: Only email module seems to use this. Other feature initialize the $_SESSION doing $formmail->clear_attached_files(); $formmail->add_attached_files()
1316
 *
1317
 * @param	string	$pathtoscan				Path to scan
1318
 * @param   string  $trackid                Track id (used to prefix name of session vars to avoid conflict)
1319
 * @return	void
1320
 */
1321
function dol_init_file_process($pathtoscan='', $trackid='')
1322
{
1323
	$listofpaths=array();
1324
	$listofnames=array();
1325
	$listofmimes=array();
1326
1327
	if ($pathtoscan)
1328
	{
1329
		$listoffiles=dol_dir_list($pathtoscan,'files');
1330
		foreach($listoffiles as $key => $val)
1331
		{
1332
			$listofpaths[]=$val['fullname'];
1333
			$listofnames[]=$val['name'];
1334
			$listofmimes[]=dol_mimetype($val['name']);
1335
		}
1336
	}
1337
    $keytoavoidconflict = empty($trackid)?'':'-'.$trackid;
1338
	$_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
1339
	$_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
1340
	$_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
1341
}
1342
1343
1344
/**
1345
 * Get and save an upload file (for example after submitting a new file a mail form).
1346
 * All information used are in db, conf, langs, user and _FILES.
1347
 * Note: This function can be used only into a HTML page context.
1348
 *
1349
 * @param	string	$upload_dir				Directory where to store uploaded file (note: used to forge $destpath = $upload_dir + filename)
1350
 * @param	int		$allowoverwrite			1=Allow overwrite existing file
1351
 * @param	int		$donotupdatesession		1=Do no edit _SESSION variable
1352
 * @param	string	$varfiles				_FILES var name
1353
 * @param	string	$savingdocmask			Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__'
1354
 * @param	string	$link					Link to add (to add a link instead of a file)
1355
 * @param   string  $trackid                Track id (used to prefix name of session vars to avoid conflict)
1356
 * @return	int                             <=0 if KO, >0 if OK
1357
 */
1358
function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='')
0 ignored issues
show
Coding Style introduced by
dol_add_file_process uses the super-global variable $_FILES which is generally not recommended.

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

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

// Better
class Router
{
    private $host;

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

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

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

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1359
{
1360
	global $db,$user,$conf,$langs;
1361
1362
	$res = 0;
1363
1364
	if (! empty($_FILES[$varfiles])) // For view $_FILES[$varfiles]['error']
1365
	{
1366
		dol_syslog('dol_add_file_process upload_dir='.$upload_dir.' allowoverwrite='.$allowoverwrite.' donotupdatesession='.$donotupdatesession.' savingdocmask='.$savingdocmask, LOG_DEBUG);
1367
		if (dol_mkdir($upload_dir) >= 0)
1368
		{
1369
			$TFile = $_FILES[$varfiles];
1370
			if (!is_array($TFile['name']))
1371
			{
1372
				foreach ($TFile as $key => &$val)
1373
				{
1374
					$val = array($val);
1375
				}
1376
			}
1377
1378
			$nbfile = count($TFile['name']);
1379
1380
			for ($i = 0; $i < $nbfile; $i++)
1381
			{
1382
				// Define $destfull (path to file including filename) and $destfile (only filename)
1383
				$destfull=$upload_dir . "/" . $TFile['name'][$i];
1384
				$destfile=$TFile['name'][$i];
1385
1386
				$savingdocmask = dol_sanitizeFileName($savingdocmask);
1387
1388
				if ($savingdocmask)
1389
				{
1390
					$destfull=$upload_dir . "/" . preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask);
1391
					$destfile=preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask);
1392
				}
1393
1394
				// lowercase extension
1395
				$info = pathinfo($destfull);
1396
				$destfull = $info['dirname'].'/'.$info['filename'].'.'.strtolower($info['extension']);
1397
				$info = pathinfo($destfile);
1398
				$destfile = $info['filename'].'.'.strtolower($info['extension']);
1399
1400
				$resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destfull, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles);
1401
1402
				if (is_numeric($resupload) && $resupload > 0)   // $resupload can be 'ErrorFileAlreadyExists'
1403
				{
1404
					global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
1405
1406
					include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1407
1408
					// Generate thumbs.
1409
					if (image_format_supported($destfull) == 1)
1410
					{
1411
					    // Create thumbs
1412
					    // We can't use $object->addThumbs here because there is no $object known
1413
1414
					    // Used on logon for example
1415
					    $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs");
1416
					    // Create mini thumbs for image (Ratio is near 16/9)
1417
					    // Used on menu or for setup page for example
1418
					    $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs");
1419
					}
1420
1421
					// Update session
1422
					if (empty($donotupdatesession))
1423
					{
1424
						include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
1425
						$formmail = new FormMail($db);
1426
						$formmail->trackid = $trackid;
1427
						$formmail->add_attached_files($destfull, $destfile, $TFile['type'][$i]);
1428
					}
1429
1430
					// Update table of files
1431
					if ($donotupdatesession)
1432
					{
1433
					    $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir);
1434
1435
					    if (! preg_match('/[\\/]temp[\\/]/', $rel_dir))     // If not a tmp dir
1436
					    {
1437
					        $filename = basename($destfile);
1438
					        $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
1439
					        $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
1440
1441
    					    include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1442
    					    $ecmfile=new EcmFiles($db);
1443
    					    $ecmfile->filepath = $rel_dir;
1444
    					    $ecmfile->filename = $filename;
1445
    					    $ecmfile->label = md5_file(dol_osencode($destfull));
1446
    					    $ecmfile->fullpath_orig = $TFile['name'][$i];
1447
    					    $ecmfile->gen_or_uploaded = 'uploaded';
1448
    					    $ecmfile->description = '';    // indexed content
1449
    					    $ecmfile->keyword = '';        // keyword content
1450
    					    $result = $ecmfile->create($user);
1451
                            if ($result < 0)
1452
                            {
1453
                                setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
1454
                            }
1455
					    }
1456
					}
1457
1458
					$res = 1;
1459
					setEventMessages($langs->trans("FileTransferComplete"), null, 'mesgs');
1460
				}
1461
				else
1462
				{
1463
					$langs->load("errors");
1464
					if ($resupload < 0)	// Unknown error
1465
					{
1466
						setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors');
1467
					}
1468
					else if (preg_match('/ErrorFileIsInfectedWithAVirus/',$resupload))	// Files infected by a virus
1469
					{
1470
						setEventMessages($langs->trans("ErrorFileIsInfectedWithAVirus"), null, 'errors');
1471
					}
1472
					else	// Known error
1473
					{
1474
						setEventMessages($langs->trans($resupload), null, 'errors');
1475
					}
1476
				}
1477
			}
1478
1479
		}
1480
	} elseif ($link) {
1481
		require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
1482
		$linkObject = new Link($db);
1483
		$linkObject->entity = $conf->entity;
1484
		$linkObject->url = $link;
1485
		$linkObject->objecttype = GETPOST('objecttype', 'alpha');
1486
		$linkObject->objectid = GETPOST('objectid', 'int');
1487
		$linkObject->label = GETPOST('label', 'alpha');
1488
		$res = $linkObject->create($user);
1489
		$langs->load('link');
1490
		if ($res > 0) {
1491
			setEventMessages($langs->trans("LinkComplete"), null, 'mesgs');
1492
		} else {
1493
			setEventMessages($langs->trans("ErrorFileNotLinked"), null, 'errors');
1494
		}
1495
	}
1496
	else
1497
	{
1498
		$langs->load("errors");
1499
		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("File")), null, 'errors');
1500
	}
1501
1502
	return $res;
1503
}
1504
1505
1506
/**
1507
 * Remove an uploaded file (for example after submitting a new file a mail form).
1508
 * All information used are in db, conf, langs, user and _FILES.
1509
 *
1510
 * @param	int		$filenb					File nb to delete
1511
 * @param	int		$donotupdatesession		1=Do not edit _SESSION variable
1512
 * @param   int		$donotdeletefile        1=Do not delete physically file
1513
 * @param   string  $trackid                Track id (used to prefix name of session vars to avoid conflict)
1514
 * @return	void
1515
 */
1516
function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile=1,$trackid='')
0 ignored issues
show
Coding Style introduced by
dol_remove_file_process uses the super-global variable $_FILES which is generally not recommended.

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

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

// Better
class Router
{
    private $host;

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

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

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

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1517
{
1518
	global $db,$user,$conf,$langs,$_FILES;
1519
1520
	$keytodelete=$filenb;
1521
	$keytodelete--;
1522
1523
	$listofpaths=array();
1524
	$listofnames=array();
1525
	$listofmimes=array();
1526
    $keytoavoidconflict = empty($trackid)?'':'-'.$trackid;
1527
	if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
1528
	if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
1529
	if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
1530
1531
	if ($keytodelete >= 0)
1532
	{
1533
		$pathtodelete=$listofpaths[$keytodelete];
1534
		$filetodelete=$listofnames[$keytodelete];
1535
		if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete,1);  // The delete of ecm database is inside the function dol_delete_file
1536
		else $result=0;
1537
		if ($result >= 0)
1538
		{
1539
			if (empty($donotdeletefile))
1540
			{
1541
				$langs->load("other");
1542
				setEventMessages($langs->trans("FileWasRemoved",$filetodelete), null, 'mesgs');
1543
			}
1544
			if (empty($donotupdatesession))
1545
			{
1546
				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
1547
				$formmail = new FormMail($db);
1548
				$formmail->trackid = $trackid;
1549
				$formmail->remove_attached_files($keytodelete);
1550
			}
1551
		}
1552
	}
1553
}
1554
1555
/**
1556
 * 	Convert an image file into anoher format.
1557
 *  This need Imagick php extension.
1558
 *
1559
 *  @param	string	$fileinput  Input file name
1560
 *  @param  string	$ext        Format of target file (It is also extension added to file if fileoutput is not provided).
1561
 *  @param	string	$fileoutput	Output filename
1562
 *  @return	int					<0 if KO, >0 if OK
1563
 */
1564
function dol_convert_file($fileinput,$ext='png',$fileoutput='')
1565
{
1566
	global $langs;
1567
1568
	$image=new Imagick();
1569
	$ret = $image->readImage($fileinput);
1570
	if ($ret)
1571
	{
1572
		$ret = $image->setImageFormat($ext);
1573
		if ($ret)
1574
		{
1575
			if (empty($fileoutput)) $fileoutput=$fileinput.".".$ext;
1576
1577
			$count = $image->getNumberImages();
1578
			$ret = $image->writeImages($fileoutput, true);
1579
			if ($ret) return $count;
1580
			else return -3;
1581
		}
1582
		else
1583
		{
1584
			return -2;
1585
		}
1586
	}
1587
	else
1588
	{
1589
		return -1;
1590
	}
1591
}
1592
1593
1594
/**
1595
 * Compress a file
1596
 *
1597
 * @param 	string	$inputfile		Source file name
1598
 * @param 	string	$outputfile		Target file name
1599
 * @param 	string	$mode			'gz' or 'bz' or 'zip'
1600
 * @return	int						<0 if KO, >0 if OK
1601
 */
1602
function dol_compress_file($inputfile, $outputfile, $mode="gz")
1603
{
1604
    $foundhandler=0;
1605
1606
    try
1607
    {
1608
        $data = implode("", file(dol_osencode($inputfile)));
1609
        if ($mode == 'gz')     { $foundhandler=1; $compressdata = gzencode($data, 9); }
1610
        elseif ($mode == 'bz') { $foundhandler=1; $compressdata = bzcompress($data, 9); }
1611
        elseif ($mode == 'zip')
1612
        {
1613
            if (defined('ODTPHP_PATHTOPCLZIP'))
1614
            {
1615
                $foundhandler=1;
1616
1617
                include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php';
1618
                $archive = new PclZip($outputfile);
1619
                $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile));
1620
                //$archive->add($inputfile);
1621
                return 1;
1622
            }
1623
        }
1624
1625
        if ($foundhandler)
1626
        {
1627
            $fp = fopen($outputfile, "w");
1628
            fwrite($fp, $compressdata);
0 ignored issues
show
Bug introduced by
The variable $compressdata 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...
1629
            fclose($fp);
1630
            return 1;
1631
        }
1632
        else
1633
        {
1634
            dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR);
1635
            return -2;
1636
        }
1637
    }
1638
    catch (Exception $e)
1639
    {
1640
        global $langs, $errormsg;
1641
        $langs->load("errors");
1642
        dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
1643
        $errormsg=$langs->trans("ErrorFailedToWriteInDir");
1644
        return -1;
1645
    }
1646
}
1647
1648
/**
1649
 * Uncompress a file
1650
 *
1651
 * @param 	string 	$inputfile		File to uncompress
1652
 * @param 	string	$outputdir		Target dir name
1653
 * @return 	array					array('error'=>'Error code') or array() if no error
1654
 */
1655
function dol_uncompress($inputfile,$outputdir)
1656
{
1657
    global $langs;
1658
1659
    if (defined('ODTPHP_PATHTOPCLZIP'))
1660
    {
1661
    	dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir);
1662
        include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php';
1663
        $archive = new PclZip($inputfile);
1664
        $result=$archive->extract(PCLZIP_OPT_PATH, $outputdir);
1665
        //var_dump($result);
1666
        if (! is_array($result) && $result <= 0) return array('error'=>$archive->errorInfo(true));
1667
        else
1668
		{
1669
			$ok=1; $errmsg='';
1670
			// Loop on each file to check result for unzipping file
1671
			foreach($result as $key => $val)
1672
			{
1673
				if ($val['status'] == 'path_creation_fail')
1674
				{
1675
					$langs->load("errors");
1676
					$ok=0;
1677
					$errmsg=$langs->trans("ErrorFailToCreateDir", $val['filename']);
1678
					break;
1679
				}
1680
			}
1681
1682
			if ($ok) return array();
1683
			else return array('error'=>$errmsg);
1684
		}
1685
    }
1686
1687
    if (class_exists('ZipArchive'))
1688
    {
1689
    	dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir);
1690
    	$zip = new ZipArchive;
1691
        $res = $zip->open($inputfile);
1692
        if ($res === TRUE)
1693
        {
1694
            $zip->extractTo($outputdir.'/');
1695
            $zip->close();
1696
            return array();
1697
        }
1698
        else
1699
        {
1700
            return array('error'=>'ErrUnzipFails');
1701
        }
1702
    }
1703
1704
    return array('error'=>'ErrNoZipEngine');
1705
}
1706
1707
1708
/**
1709
 * Compress a directory and subdirectories into a package file.
1710
 *
1711
 * @param 	string	$inputdir		Source dir name
1712
 * @param 	string	$outputfile		Target file name (output directory must exists and be writable)
1713
 * @param 	string	$mode			'zip'
1714
 * @return	int						<0 if KO, >0 if OK
1715
 */
1716
function dol_compress_dir($inputdir, $outputfile, $mode="zip")
1717
{
1718
    $foundhandler=0;
1719
1720
    dol_syslog("Try to zip dir ".$inputdir." into ".$outputdir." mode=".$mode);
0 ignored issues
show
Bug introduced by
The variable $outputdir 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...
1721
1722
    if (! dol_is_dir(dirname($outputfile)) || ! is_writable(dirname($outputfile)))
1723
    {
1724
    	global $langs, $errormsg;
1725
    	$langs->load("errors");
1726
    	$errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile);
1727
		return -3;
1728
    }
1729
1730
    try
1731
    {
1732
        if ($mode == 'gz')     { $foundhandler=0; }
1733
        elseif ($mode == 'bz') { $foundhandler=0; }
1734
        elseif ($mode == 'zip')
1735
        {
1736
            /*if (defined('ODTPHP_PATHTOPCLZIP'))
1737
            {
1738
                $foundhandler=0;        // TODO implement this
1739
1740
                include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php';
1741
                $archive = new PclZip($outputfile);
1742
                $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile));
1743
                //$archive->add($inputfile);
1744
                return 1;
1745
            }
1746
            else*/
1747
            if (class_exists('ZipArchive'))
1748
            {
1749
                $foundhandler=1;
1750
1751
                // Initialize archive object
1752
                $zip = new ZipArchive();
1753
                $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
1754
1755
                // Create recursive directory iterator
1756
                /** @var SplFileInfo[] $files */
1757
                $files = new RecursiveIteratorIterator(
1758
                    new RecursiveDirectoryIterator($inputdir),
1759
                    RecursiveIteratorIterator::LEAVES_ONLY
1760
                    );
1761
1762
                foreach ($files as $name => $file)
1763
                {
1764
                    // Skip directories (they would be added automatically)
1765
                    if (!$file->isDir())
1766
                    {
1767
                        // Get real and relative path for current file
1768
                        $filePath = $file->getRealPath();
1769
                        $relativePath = substr($filePath, strlen($inputdir) + 1);
1770
1771
                        // Add current file to archive
1772
                        $zip->addFile($filePath, $relativePath);
1773
                    }
1774
                }
1775
1776
                // Zip archive will be created only after closing object
1777
                $zip->close();
1778
1779
                return 1;
1780
            }
1781
        }
1782
1783
        if (! $foundhandler)
1784
        {
1785
            dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR);
1786
            return -2;
1787
        }
1788
        else
1789
        {
1790
        	return 0;
1791
        }
1792
    }
1793
    catch (Exception $e)
1794
    {
1795
        global $langs, $errormsg;
1796
        $langs->load("errors");
1797
        dol_syslog("Failed to open file ".$outputfile, LOG_ERR);
1798
        dol_syslog($e->getMessage(), LOG_ERR);
1799
        $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile);
1800
        return -1;
1801
    }
1802
}
1803
1804
1805
1806
/**
1807
 * Return file(s) into a directory (by default most recent)
1808
 *
1809
 * @param 	string		$dir			Directory to scan
1810
 * @param	string		$regexfilter	Regex filter to restrict list. This regex value must be escaped for '/', since this char is used for preg_match function
1811
 * @param	array		$excludefilter  Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). This regex value must be escaped for '/', since this char is used for preg_match function
1812
 * @param	int			$nohook			Disable all hooks
1813
 * @param	int			$mode			0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only
1814
 * @return	string						Full path to most recent file
1815
 */
1816
function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta|_preview.*\.png)$','^\.'),$nohook=false,$mode='')
1817
{
1818
    $tmparray=dol_dir_list($dir,'files',0,$regexfilter,$excludefilter,'date',SORT_DESC,$mode,$nohook);
0 ignored issues
show
Bug introduced by
It seems like $nohook defined by parameter $nohook on line 1816 can also be of type false; however, dol_dir_list() does only seem to accept integer, 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...
1819
    return $tmparray[0];
1820
}
1821
1822
/**
1823
 * Security check when accessing to a document (used by document.php, viewimage.php and webservices)
1824
 *
1825
 * @param	string	$modulepart			Module of document ('module', 'module_user_temp', 'module_user' or 'module_temp')
1826
 * @param	string	$original_file		Relative path with filename, relative to modulepart.
1827
 * @param	string	$entity				Restrict onto entity (0=no restriction)
1828
 * @param  	User	$fuser				User object (forced)
1829
 * @param	string	$refname			Ref of object to check permission for external users (autodetect if not provided)
1830
 * @param   string  $mode               Check permission for 'read' or 'write'
1831
 * @return	mixed						Array with access information : 'accessallowed' & 'sqlprotectagainstexternals' & 'original_file' (as a full path name)
1832
 * @see restrictedArea
1833
 */
1834
function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser='', $refname='', $mode='read')
1835
{
1836
	global $user, $conf, $db;
1837
	global $dolibarr_main_data_root;
1838
1839
	if (! is_object($fuser)) $fuser=$user;
1840
1841
	if (empty($modulepart)) return 'ErrorBadParameter';
1842
	if (empty($entity)) $entity=0;
1843
	dol_syslog('modulepart='.$modulepart.' original_file='.$original_file);
1844
	// We define $accessallowed and $sqlprotectagainstexternals
1845
	$accessallowed=0;
1846
	$sqlprotectagainstexternals='';
1847
	$ret=array();
1848
1849
    // Find the subdirectory name as the reference. For exemple original_file='10/myfile.pdf' -> refname='10'
1850
	if (empty($refname)) $refname=basename(dirname($original_file)."/");
1851
1852
	$relative_original_file = $original_file;
1853
1854
	// Define possible keys to use for permission check
1855
	$lire='lire'; $read='read'; $download='download';
1856
	if ($mode == 'write')
1857
	{
1858
	    $lire='creer'; $read='write'; $download='upload';
1859
	}
1860
1861
	// Wrapping for miscellaneous medias files
1862
	if ($modulepart == 'medias' && !empty($dolibarr_main_data_root))
1863
	{
1864
	    $accessallowed=1;
1865
	    $original_file=$dolibarr_main_data_root.'/medias/'.$original_file;
1866
	}
1867
	// Wrapping for *.log files, like when used with url http://.../document.php?modulepart=logs&file=dolibarr.log
1868
	elseif ($modulepart == 'logs' && !empty($dolibarr_main_data_root))
1869
	{
1870
	    $accessallowed=($user->admin && basename($original_file) == $original_file && preg_match('/^dolibarr.*\.log$/', basename($original_file)));
1871
	    $original_file=$dolibarr_main_data_root.'/'.$original_file;
1872
	}
1873
	// Wrapping for some images
1874
	elseif (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output))
1875
	{
1876
		$accessallowed=1;
1877
		$original_file=$conf->mycompany->dir_output.'/logos/'.$original_file;
1878
	}
1879
	// Wrapping for users photos
1880
	elseif ($modulepart == 'userphoto' && !empty($conf->user->dir_output))
1881
	{
1882
		$accessallowed=1;
1883
		$original_file=$conf->user->dir_output.'/'.$original_file;
1884
	}
1885
	// Wrapping for members photos
1886
	elseif ($modulepart == 'memberphoto' && !empty($conf->adherent->dir_output))
1887
	{
1888
		$accessallowed=1;
1889
		$original_file=$conf->adherent->dir_output.'/'.$original_file;
1890
	}
1891
	// Wrapping pour les apercu factures
1892
	elseif ($modulepart == 'apercufacture' && !empty($conf->facture->dir_output))
1893
	{
1894
		if ($fuser->rights->facture->{$lire}) $accessallowed=1;
1895
		$original_file=$conf->facture->dir_output.'/'.$original_file;
1896
	}
1897
	// Wrapping pour les apercu propal
1898
	elseif ($modulepart == 'apercupropal' && !empty($conf->propal->dir_output))
1899
	{
1900
		if ($fuser->rights->propale->{$lire}) $accessallowed=1;
1901
		$original_file=$conf->propal->dir_output.'/'.$original_file;
1902
	}
1903
	// Wrapping pour les apercu commande
1904
	elseif ($modulepart == 'apercucommande' && !empty($conf->commande->dir_output))
1905
	{
1906
		if ($fuser->rights->commande->{$lire}) $accessallowed=1;
1907
		$original_file=$conf->commande->dir_output.'/'.$original_file;
1908
	}
1909
	// Wrapping pour les apercu intervention
1910
	elseif (($modulepart == 'apercufichinter' || $modulepart == 'apercuficheinter') && !empty($conf->ficheinter->dir_output))
1911
	{
1912
	    if ($fuser->rights->ficheinter->{$lire}) $accessallowed=1;
1913
	    $original_file=$conf->ficheinter->dir_output.'/'.$original_file;
1914
	}
1915
	// Wrapping pour les apercu conat
1916
	elseif (($modulepart == 'apercucontract') && !empty($conf->contrat->dir_output))
1917
	{
1918
	    if ($fuser->rights->contrat->{$lire}) $accessallowed=1;
1919
	    $original_file=$conf->contrat->dir_output.'/'.$original_file;
1920
	}
1921
	// Wrapping pour les apercu supplier proposal
1922
	elseif (($modulepart == 'apercusupplier_proposal' || $modulepart == 'apercusupplier_proposal') && !empty($conf->supplier_proposal->dir_output))
1923
	{
1924
	    if ($fuser->rights->supplier_proposal->{$lire}) $accessallowed=1;
1925
	    $original_file=$conf->supplier_proposal->dir_output.'/'.$original_file;
1926
	}
1927
	// Wrapping pour les apercu supplier order
1928
	elseif (($modulepart == 'apercusupplier_order' || $modulepart == 'apercusupplier_order') && !empty($conf->fournisseur->commande->dir_output))
1929
	{
1930
	    if ($fuser->rights->fournisseur->commande->{$lire}) $accessallowed=1;
1931
	    $original_file=$conf->fournisseur->commande->dir_output.'/'.$original_file;
1932
	}
1933
	// Wrapping pour les apercu supplier invoice
1934
	elseif (($modulepart == 'apercusupplier_invoice' || $modulepart == 'apercusupplier_invoice') && !empty($conf->fournisseur->facture->dir_output))
1935
	{
1936
	    if ($fuser->rights->fournisseur->facture->{$lire}) $accessallowed=1;
1937
	    $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file;
1938
	}
1939
	// Wrapping pour les apercu supplier invoice
1940
	elseif (($modulepart == 'apercuexpensereport') && !empty($conf->expensereport->dir_output))
1941
	{
1942
	    if ($fuser->rights->expensereport->{$lire}) $accessallowed=1;
1943
	    $original_file=$conf->expensereport->dir_output.'/'.$original_file;
1944
	}
1945
	// Wrapping pour les images des stats propales
1946
	elseif ($modulepart == 'propalstats' && !empty($conf->propal->dir_temp))
1947
	{
1948
		if ($fuser->rights->propale->{$lire}) $accessallowed=1;
1949
		$original_file=$conf->propal->dir_temp.'/'.$original_file;
1950
	}
1951
	// Wrapping pour les images des stats commandes
1952
	elseif ($modulepart == 'orderstats' && !empty($conf->commande->dir_temp))
1953
	{
1954
		if ($fuser->rights->commande->{$lire}) $accessallowed=1;
1955
		$original_file=$conf->commande->dir_temp.'/'.$original_file;
1956
	}
1957
	elseif ($modulepart == 'orderstatssupplier' && !empty($conf->fournisseur->dir_output))
1958
	{
1959
		if ($fuser->rights->fournisseur->commande->{$lire}) $accessallowed=1;
1960
		$original_file=$conf->fournisseur->commande->dir_temp.'/'.$original_file;
1961
	}
1962
	// Wrapping pour les images des stats factures
1963
	elseif ($modulepart == 'billstats' && !empty($conf->facture->dir_temp))
1964
	{
1965
		if ($fuser->rights->facture->{$lire}) $accessallowed=1;
1966
		$original_file=$conf->facture->dir_temp.'/'.$original_file;
1967
	}
1968
	elseif ($modulepart == 'billstatssupplier' && !empty($conf->fournisseur->dir_output))
1969
	{
1970
		if ($fuser->rights->fournisseur->facture->{$lire}) $accessallowed=1;
1971
		$original_file=$conf->fournisseur->dir_output.'/facture/temp/'.$original_file;
1972
	}
1973
	// Wrapping pour les images des stats expeditions
1974
	elseif ($modulepart == 'expeditionstats' && !empty($conf->expedition->dir_temp))
1975
	{
1976
		if ($fuser->rights->expedition->{$lire}) $accessallowed=1;
1977
		$original_file=$conf->expedition->dir_temp.'/'.$original_file;
1978
	}
1979
	// Wrapping pour les images des stats expeditions
1980
	elseif ($modulepart == 'tripsexpensesstats' && !empty($conf->deplacement->dir_temp))
1981
	{
1982
		if ($fuser->rights->deplacement->{$lire}) $accessallowed=1;
1983
		$original_file=$conf->deplacement->dir_temp.'/'.$original_file;
1984
	}
1985
	// Wrapping pour les images des stats expeditions
1986
	elseif ($modulepart == 'memberstats' && !empty($conf->adherent->dir_temp))
1987
	{
1988
		if ($fuser->rights->adherent->{$lire}) $accessallowed=1;
1989
		$original_file=$conf->adherent->dir_temp.'/'.$original_file;
1990
	}
1991
	// Wrapping pour les images des stats produits
1992
	elseif (preg_match('/^productstats_/i',$modulepart) && !empty($conf->product->dir_temp))
1993
	{
1994
		if ($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) $accessallowed=1;
1995
		$original_file=(!empty($conf->product->multidir_temp[$entity])?$conf->product->multidir_temp[$entity]:$conf->service->multidir_temp[$entity]).'/'.$original_file;
1996
	}
1997
	// Wrapping for taxes
1998
	elseif ($modulepart == 'tax' && !empty($conf->tax->dir_output))
1999
	{
2000
		if ($fuser->rights->tax->charges->{$lire}) $accessallowed=1;
2001
		$original_file=$conf->tax->dir_output.'/'.$original_file;
2002
	}
2003
	// Wrapping for events
2004
	elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output))
2005
	{
2006
		if ($fuser->rights->agenda->myactions->{$read}) $accessallowed=1;
2007
		$original_file=$conf->agenda->dir_output.'/'.$original_file;
2008
	}
2009
	// Wrapping for categories
2010
	elseif ($modulepart == 'category' && !empty($conf->categorie->dir_output))
2011
	{
2012
		if ($fuser->rights->categorie->{$lire}) $accessallowed=1;
2013
		$original_file=$conf->categorie->multidir_output[$entity].'/'.$original_file;
2014
	}
2015
	// Wrapping pour les prelevements
2016
	elseif ($modulepart == 'prelevement' && !empty($conf->prelevement->dir_output))
2017
	{
2018
		if ($fuser->rights->prelevement->bons->{$lire} || preg_match('/^specimen/i',$original_file)) $accessallowed=1;
2019
		$original_file=$conf->prelevement->dir_output.'/'.$original_file;
2020
	}
2021
	// Wrapping pour les graph energie
2022
	elseif ($modulepart == 'graph_stock' && !empty($conf->stock->dir_temp))
2023
	{
2024
		$accessallowed=1;
2025
		$original_file=$conf->stock->dir_temp.'/'.$original_file;
2026
	}
2027
	// Wrapping pour les graph fournisseurs
2028
	elseif ($modulepart == 'graph_fourn' && !empty($conf->fournisseur->dir_temp))
2029
	{
2030
		$accessallowed=1;
2031
		$original_file=$conf->fournisseur->dir_temp.'/'.$original_file;
2032
	}
2033
	// Wrapping pour les graph des produits
2034
	elseif ($modulepart == 'graph_product' && !empty($conf->product->dir_temp))
2035
	{
2036
		$accessallowed=1;
2037
		$original_file=$conf->product->multidir_temp[$entity].'/'.$original_file;
2038
	}
2039
	// Wrapping pour les code barre
2040
	elseif ($modulepart == 'barcode')
2041
	{
2042
		$accessallowed=1;
2043
		// If viewimage is called for barcode, we try to output an image on the fly, with no build of file on disk.
2044
		//$original_file=$conf->barcode->dir_temp.'/'.$original_file;
2045
		$original_file='';
2046
	}
2047
	// Wrapping pour les icones de background des mailings
2048
	elseif ($modulepart == 'iconmailing' && !empty($conf->mailing->dir_temp))
2049
	{
2050
		$accessallowed=1;
2051
		$original_file=$conf->mailing->dir_temp.'/'.$original_file;
2052
	}
2053
	// Wrapping pour le scanner
2054
	elseif ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp))
2055
	{
2056
		$accessallowed=1;
2057
		$original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file;
2058
	}
2059
	// Wrapping pour les images fckeditor
2060
	elseif ($modulepart == 'fckeditor' && !empty($conf->fckeditor->dir_output))
2061
	{
2062
		$accessallowed=1;
2063
		$original_file=$conf->fckeditor->dir_output.'/'.$original_file;
2064
	}
2065
2066
	// Wrapping for users
2067
	else if ($modulepart == 'user' && !empty($conf->user->dir_output))
2068
	{
2069
        $canreaduser=(! empty($fuser->admin) || $fuser->rights->user->user->{$lire});
2070
        if ($fuser->id == (int) $refname) { $canreaduser=1; } // A user can always read its own card
2071
        if ($canreaduser || preg_match('/^specimen/i',$original_file))
2072
	    {
2073
	        $accessallowed=1;
2074
	    }
2075
	    $original_file=$conf->user->dir_output.'/'.$original_file;
2076
	}
2077
2078
	// Wrapping for third parties
2079
	else if (($modulepart == 'company' || $modulepart == 'societe') && !empty($conf->societe->dir_output))
2080
	{
2081
		if ($fuser->rights->societe->{$lire} || preg_match('/^specimen/i',$original_file))
2082
		{
2083
			$accessallowed=1;
2084
		}
2085
		$original_file=$conf->societe->multidir_output[$entity].'/'.$original_file;
2086
		$sqlprotectagainstexternals = "SELECT rowid as fk_soc FROM ".MAIN_DB_PREFIX."societe WHERE rowid='".$db->escape($refname)."' AND entity IN (".getEntity('societe').")";
2087
	}
2088
2089
	// Wrapping for contact
2090
	else if ($modulepart == 'contact' && !empty($conf->societe->dir_output))
2091
	{
2092
		if ($fuser->rights->societe->{$lire})
2093
		{
2094
			$accessallowed=1;
2095
		}
2096
		$original_file=$conf->societe->multidir_output[$entity].'/contact/'.$original_file;
2097
	}
2098
2099
	// Wrapping for invoices
2100
	else if (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output))
2101
	{
2102
		if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2103
		{
2104
			$accessallowed=1;
2105
		}
2106
		$original_file=$conf->facture->dir_output.'/'.$original_file;
2107
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2108
	}
2109
	// Wrapping for mass actions
2110
	else if ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->dir_output))
2111
	{
2112
	    if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i',$original_file))
2113
	    {
2114
	        $accessallowed=1;
2115
	    }
2116
	    $original_file=$conf->propal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2117
	}
2118
	else if ($modulepart == 'massfilesarea_orders')
2119
	{
2120
	    if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2121
	    {
2122
	        $accessallowed=1;
2123
	    }
2124
	    $original_file=$conf->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2125
	}
2126
	else if ($modulepart == 'massfilesarea_invoices')
2127
	{
2128
	    if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2129
	    {
2130
	        $accessallowed=1;
2131
	    }
2132
	    $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2133
	}
2134
	else if ($modulepart == 'massfilesarea_expensereport')
2135
	{
2136
	    if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2137
	    {
2138
	        $accessallowed=1;
2139
	    }
2140
	    $original_file=$conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2141
	}
2142
	else if ($modulepart == 'massfilesarea_interventions')
2143
	{
2144
	    if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file))
2145
	    {
2146
	        $accessallowed=1;
2147
	    }
2148
	    $original_file=$conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2149
	}
2150
	else if ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->propal->dir_output))
2151
	{
2152
	    if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i',$original_file))
2153
	    {
2154
	        $accessallowed=1;
2155
	    }
2156
	    $original_file=$conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2157
	}
2158
	else if ($modulepart == 'massfilesarea_supplier_order')
2159
	{
2160
	    if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2161
	    {
2162
	        $accessallowed=1;
2163
	    }
2164
	    $original_file=$conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2165
	}
2166
	else if ($modulepart == 'massfilesarea_supplier_invoice')
2167
	{
2168
	    if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2169
	    {
2170
	        $accessallowed=1;
2171
	    }
2172
	    $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2173
	}
2174
2175
	// Wrapping for interventions
2176
	else if (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output))
2177
	{
2178
		if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file))
2179
		{
2180
			$accessallowed=1;
2181
		}
2182
		$original_file=$conf->ficheinter->dir_output.'/'.$original_file;
2183
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2184
	}
2185
2186
	// Wrapping pour les deplacements et notes de frais
2187
	else if ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output))
2188
	{
2189
		if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i',$original_file))
2190
		{
2191
			$accessallowed=1;
2192
		}
2193
		$original_file=$conf->deplacement->dir_output.'/'.$original_file;
2194
		//$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2195
	}
2196
	// Wrapping pour les propales
2197
	else if ($modulepart == 'propal' && !empty($conf->propal->dir_output))
2198
	{
2199
		if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i',$original_file))
2200
		{
2201
			$accessallowed=1;
2202
		}
2203
2204
		$original_file=$conf->propal->dir_output.'/'.$original_file;
2205
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."propal WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2206
	}
2207
2208
	// Wrapping pour les commandes
2209
	else if (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output))
2210
	{
2211
		if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2212
		{
2213
			$accessallowed=1;
2214
		}
2215
		$original_file=$conf->commande->dir_output.'/'.$original_file;
2216
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2217
	}
2218
2219
	// Wrapping pour les projets
2220
	else if ($modulepart == 'project' && !empty($conf->projet->dir_output))
2221
	{
2222
		if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file))
2223
		{
2224
			$accessallowed=1;
2225
		}
2226
		$original_file=$conf->projet->dir_output.'/'.$original_file;
2227
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")";
2228
	}
2229
	else if ($modulepart == 'project_task' && !empty($conf->projet->dir_output))
2230
	{
2231
		if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file))
2232
		{
2233
			$accessallowed=1;
2234
		}
2235
		$original_file=$conf->projet->dir_output.'/'.$original_file;
2236
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")";
2237
	}
2238
2239
	// Wrapping pour les commandes fournisseurs
2240
	else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output))
2241
	{
2242
		if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2243
		{
2244
			$accessallowed=1;
2245
		}
2246
		$original_file=$conf->fournisseur->commande->dir_output.'/'.$original_file;
2247
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande_fournisseur WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2248
	}
2249
2250
	// Wrapping pour les factures fournisseurs
2251
	else if (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output))
2252
	{
2253
		if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2254
		{
2255
			$accessallowed=1;
2256
		}
2257
		$original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file;
2258
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE facnumber='".$db->escape($refname)."' AND entity=".$conf->entity;
2259
	}
2260
	// Wrapping pour les rapport de paiements
2261
	else if ($modulepart == 'supplier_payment')
2262
	{
2263
		if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2264
		{
2265
			$accessallowed=1;
2266
		}
2267
		$original_file=$conf->fournisseur->payment->dir_output.'/'.$original_file;
2268
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."paiementfournisseur WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2269
	}
2270
2271
	// Wrapping pour les rapport de paiements
2272
	else if ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output))
2273
	{
2274
		if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2275
		{
2276
			$accessallowed=1;
2277
		}
2278
		if ($fuser->societe_id > 0) $original_file=$conf->facture->dir_output.'/payments/private/'.$fuser->id.'/'.$original_file;
2279
		else $original_file=$conf->facture->dir_output.'/payments/'.$original_file;
2280
	}
2281
2282
	// Wrapping for accounting exports
2283
	else if ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output))
2284
	{
2285
		if ($fuser->rights->accounting->bind->write || preg_match('/^specimen/i',$original_file))
2286
		{
2287
			$accessallowed=1;
2288
		}
2289
		$original_file=$conf->accounting->dir_output.'/'.$original_file;
2290
	}
2291
2292
	// Wrapping pour les expedition
2293
	else if ($modulepart == 'expedition' && !empty($conf->expedition->dir_output))
2294
	{
2295
		if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i',$original_file))
2296
		{
2297
			$accessallowed=1;
2298
		}
2299
		$original_file=$conf->expedition->dir_output."/sending/".$original_file;
2300
	}
2301
	// Wrapping pour les bons de livraison
2302
	else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output))
2303
	{
2304
		if ($fuser->rights->expedition->livraison->{$lire} || preg_match('/^specimen/i',$original_file))
2305
		{
2306
			$accessallowed=1;
2307
		}
2308
		$original_file=$conf->expedition->dir_output."/receipt/".$original_file;
2309
	}
2310
2311
	// Wrapping pour les actions
2312
	else if ($modulepart == 'actions' && !empty($conf->agenda->dir_output))
2313
	{
2314
		if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i',$original_file))
2315
		{
2316
			$accessallowed=1;
2317
		}
2318
		$original_file=$conf->agenda->dir_output.'/'.$original_file;
2319
	}
2320
2321
	// Wrapping pour les actions
2322
	else if ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp))
2323
	{
2324
		if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i',$original_file))
2325
		{
2326
			$accessallowed=1;
2327
		}
2328
		$original_file = $conf->agenda->dir_temp."/".$original_file;
2329
	}
2330
2331
	// Wrapping pour les produits et services
2332
	else if ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service')
2333
	{
2334
		if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i',$original_file))
2335
		{
2336
			$accessallowed=1;
2337
		}
2338
		if (! empty($conf->product->enabled)) $original_file=$conf->product->multidir_output[$entity].'/'.$original_file;
2339
		elseif (! empty($conf->service->enabled)) $original_file=$conf->service->multidir_output[$entity].'/'.$original_file;
2340
	}
2341
2342
	// Wrapping pour les contrats
2343
	else if ($modulepart == 'contract' && !empty($conf->contrat->dir_output))
2344
	{
2345
		if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file))
2346
		{
2347
			$accessallowed=1;
2348
		}
2349
		$original_file=$conf->contrat->dir_output.'/'.$original_file;
2350
		$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."contrat WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('contract').")";
2351
	}
2352
2353
	// Wrapping pour les dons
2354
	else if ($modulepart == 'donation' && !empty($conf->don->dir_output))
2355
	{
2356
		if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i',$original_file))
2357
		{
2358
			$accessallowed=1;
2359
		}
2360
		$original_file=$conf->don->dir_output.'/'.$original_file;
2361
	}
2362
2363
	// Wrapping pour les dons
2364
	else if ($modulepart == 'dolresource' && !empty($conf->resource->dir_output))
2365
	{
2366
		if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i',$original_file))
2367
		{
2368
			$accessallowed=1;
2369
		}
2370
		$original_file=$conf->resource->dir_output.'/'.$original_file;
2371
	}
2372
2373
	// Wrapping pour les remises de cheques
2374
	else if ($modulepart == 'remisecheque' && !empty($conf->banque->dir_output))
2375
	{
2376
		if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i',$original_file))
2377
		{
2378
			$accessallowed=1;
2379
		}
2380
2381
		$original_file=$conf->bank->dir_output.'/checkdeposits/'.$original_file;		// original_file should contains relative path so include the get_exdir result
2382
	}
2383
2384
	// Wrapping for bank
2385
	else if ($modulepart == 'bank' && !empty($conf->bank->dir_output))
2386
	{
2387
		if ($fuser->rights->banque->{$lire})
2388
		{
2389
			$accessallowed=1;
2390
		}
2391
		$original_file=$conf->bank->dir_output.'/'.$original_file;
2392
	}
2393
2394
	// Wrapping for export module
2395
	else if ($modulepart == 'export' && !empty($conf->export->dir_temp))
2396
	{
2397
		// Aucun test necessaire car on force le rep de download sur
2398
		// le rep export qui est propre a l'utilisateur
2399
		$accessallowed=1;
2400
		$original_file=$conf->export->dir_temp.'/'.$fuser->id.'/'.$original_file;
2401
	}
2402
2403
	// Wrapping for import module
2404
	else if ($modulepart == 'import' && !empty($conf->import->dir_temp))
2405
	{
2406
		$accessallowed=1;
2407
		$original_file=$conf->import->dir_temp.'/'.$original_file;
2408
	}
2409
2410
	// Wrapping pour l'editeur wysiwyg
2411
	else if ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output))
2412
	{
2413
		$accessallowed=1;
2414
		$original_file=$conf->fckeditor->dir_output.'/'.$original_file;
2415
	}
2416
2417
	// Wrapping for backups
2418
	else if ($modulepart == 'systemtools' && !empty($conf->admin->dir_output))
2419
	{
2420
		if ($fuser->admin) $accessallowed=1;
2421
		$original_file=$conf->admin->dir_output.'/'.$original_file;
2422
	}
2423
2424
	// Wrapping for upload file test
2425
	else if ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp))
2426
	{
2427
		if ($fuser->admin) $accessallowed=1;
2428
		$original_file=$conf->admin->dir_temp.'/'.$original_file;
2429
	}
2430
2431
	// Wrapping pour BitTorrent
2432
	else if ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output))
2433
	{
2434
		$accessallowed=1;
2435
		$dir='files';
2436
		if (dol_mimetype($original_file) == 'application/x-bittorrent') $dir='torrents';
2437
		$original_file=$conf->bittorrent->dir_output.'/'.$dir.'/'.$original_file;
2438
	}
2439
2440
	// Wrapping pour Foundation module
2441
	else if ($modulepart == 'member' && !empty($conf->adherent->dir_output))
2442
	{
2443
		if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i',$original_file))
2444
		{
2445
			$accessallowed=1;
2446
		}
2447
		$original_file=$conf->adherent->dir_output.'/'.$original_file;
2448
	}
2449
2450
	// Wrapping for Scanner
2451
	else if ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp))
2452
	{
2453
		$accessallowed=1;
2454
		$original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file;
2455
	}
2456
2457
    // GENERIC Wrapping
2458
    // If modulepart=module_user_temp	Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp/iduser
2459
    // If modulepart=module_temp		Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp
2460
    // If modulepart=module_user		Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/iduser
2461
    // If modulepart=module				Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart
2462
    else
2463
	{
2464
	    if (preg_match('/^specimen/i',$original_file))	$accessallowed=1;    // If link to a file called specimen. Test must be done before changing $original_file int full path.
2465
	    if ($fuser->admin) $accessallowed=1;    // If user is admin
2466
2467
		// Define $accessallowed
2468
		if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg))
2469
		{
2470
			if (empty($conf->{$reg[1]}->dir_temp))	// modulepart not supported
2471
			{
2472
				dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2473
				exit;
2474
			}
2475
		    if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1;
2476
			$original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file;
2477
		}
2478
		else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg))
2479
		{
2480
			if (empty($conf->{$reg[1]}->dir_temp))	// modulepart not supported
2481
			{
2482
				dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2483
				exit;
2484
			}
2485
		    if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1;
2486
			$original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file;
2487
		}
2488
		else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg))
2489
		{
2490
			if (empty($conf->{$reg[1]}->dir_output))	// modulepart not supported
2491
			{
2492
				dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2493
				exit;
2494
			}
2495
		    if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1;
2496
			$original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file;
2497
		}
2498
		else
2499
		{
2500
			if (empty($conf->$modulepart->dir_output))	// modulepart not supported
2501
			{
2502
				dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2503
				exit;
2504
			}
2505
2506
			$perm=GETPOST('perm');
2507
			$subperm=GETPOST('subperm');
2508
			if ($perm || $subperm)
2509
			{
2510
				if (($perm && ! $subperm && $fuser->rights->$modulepart->$perm) || ($perm && $subperm && $fuser->rights->$modulepart->$perm->$subperm)) $accessallowed=1;
2511
				$original_file=$conf->$modulepart->dir_output.'/'.$original_file;
2512
			}
2513
			else
2514
			{
2515
				if ($fuser->rights->$modulepart->{$lire} || $fuser->rights->$modulepart->{$read}) $accessallowed=1;
2516
				$original_file=$conf->$modulepart->dir_output.'/'.$original_file;
2517
			}
2518
		}
2519
2520
		// For modules who wants to manage different levels of permissions for documents
2521
		$subPermCategoryConstName = strtoupper($modulepart).'_SUBPERMCATEGORY_FOR_DOCUMENTS';
2522
		if (! empty($conf->global->$subPermCategoryConstName))
2523
		{
2524
			$subPermCategory = $conf->global->$subPermCategoryConstName;
2525
			if (! empty($subPermCategory) && (($fuser->rights->$modulepart->$subPermCategory->{$lire}) || ($fuser->rights->$modulepart->$subPermCategory->{$read}) || ($fuser->rights->$modulepart->$subPermCategory->{$download})))
2526
			{
2527
				$accessallowed=1;
2528
			}
2529
		}
2530
2531
		// Define $sqlprotectagainstexternals for modules who want to protect access using a SQL query.
2532
		$sqlProtectConstName = strtoupper($modulepart).'_SQLPROTECTAGAINSTEXTERNALS_FOR_DOCUMENTS';
2533
		if (! empty($conf->global->$sqlProtectConstName))	// If module want to define its own $sqlprotectagainstexternals
2534
		{
2535
			// Example: mymodule__SQLPROTECTAGAINSTEXTERNALS_FOR_DOCUMENTS = "SELECT fk_soc FROM ".MAIN_DB_PREFIX.$modulepart." WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2536
			eval('$sqlprotectagainstexternals = "'.$conf->global->$sqlProtectConstName.'";');
0 ignored issues
show
Coding Style introduced by
The function dol_check_secure_access_document() contains an eval expression.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
2537
		}
2538
	}
2539
2540
	$ret = array(
2541
		'accessallowed' => $accessallowed,
2542
		'sqlprotectagainstexternals'=>$sqlprotectagainstexternals,
2543
		'original_file'=>$original_file
2544
	);
2545
2546
	return $ret;
2547
}
2548
2549
/**
2550
 * Store object in file.
2551
 *
2552
 * @param string $directory Directory of cache
2553
 * @param string $filename Name of filecache
2554
 * @param mixed $object Object to store in cachefile
2555
 * @return void
2556
 */
2557
function dol_filecache($directory, $filename, $object)
2558
{
2559
    if (! dol_is_dir($directory)) dol_mkdir($directory);
2560
    $cachefile = $directory . $filename;
2561
    file_put_contents($cachefile, serialize($object), LOCK_EX);
2562
    @chmod($cachefile, 0644);
2563
}
2564
2565
/**
2566
 * Test if Refresh needed.
2567
 *
2568
 * @param string $directory Directory of cache
2569
 * @param string $filename Name of filecache
2570
 * @param int $cachetime Cachetime delay
2571
 * @return boolean 0 no refresh 1 if refresh needed
2572
 */
2573
function dol_cache_refresh($directory, $filename, $cachetime)
2574
{
2575
    $now = dol_now();
2576
    $cachefile = $directory . $filename;
2577
    $refresh = !file_exists($cachefile) || ($now-$cachetime) > dol_filemtime($cachefile);
2578
    return $refresh;
2579
}
2580
2581
/**
2582
 * Read object from cachefile.
2583
 *
2584
 * @param string $directory Directory of cache
2585
 * @param string $filename Name of filecache
2586
 * @return mixed Unserialise from file
2587
 */
2588
function dol_readcachefile($directory, $filename)
2589
{
2590
    $cachefile = $directory . $filename;
2591
    $object = unserialize(file_get_contents($cachefile));
2592
    return $object;
2593
}
2594