dolibarr  7.0.0-beta
files.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2008-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2012-2015 Regis Houssin <regis.houssin@capnetworks.com>
4  * Copyright (C) 2012-2016 Juanjo Menent <jmenent@2byte.es>
5  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
6  * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
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 
35 function dol_basename($pathfile)
36 {
37  return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/'));
38 }
39 
58 function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $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  $fullpathfile=($newpath?$newpath.'/':'').$file;
111 
112  $qualified=1;
113 
114  // Define excludefilterarray
115  $excludefilterarray=array('^\.');
116  if (is_array($excludefilter))
117  {
118  $excludefilterarray=array_merge($excludefilterarray,$excludefilter);
119  }
120  else if ($excludefilter) $excludefilterarray[]=$excludefilter;
121  // Check if file is qualified
122  foreach($excludefilterarray as $filt)
123  {
124  if (preg_match('/'.$filt.'/i', $file) || preg_match('/'.$filt.'/i', $fullpathfile)) {
125  $qualified=0; break;
126  }
127  }
128  //print $fullpathfile.' '.$file.' '.$qualified.'<br>';
129 
130  if ($qualified)
131  {
132  $isdir=is_dir(dol_osencode($path."/".$file));
133  // Check whether this is a file or directory and whether we're interested in that type
134  if ($isdir && (($types=="directories") || ($types=="all") || $recursive))
135  {
136  // Add entry into file_list array
137  if (($types=="directories") || ($types=="all"))
138  {
139  if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file);
140  if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file);
141 
142  if (! $filter || preg_match('/'.$filter.'/i',$file)) // We do not search key $filter into all $path, only into $file part
143  {
144  preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg);
145  $level1name=(isset($reg[1])?$reg[1]:'');
146  $file_list[] = array(
147  "name" => $file,
148  "path" => $path,
149  "level1name" => $level1name,
150  "relativename" => ($relativename?$relativename.'/':'').$file,
151  "fullname" => $path.'/'.$file,
152  "date" => $filedate,
153  "size" => $filesize,
154  "type" => 'dir'
155  );
156  }
157  }
158 
159  // if we're in a directory and we want recursive behavior, call this function again
160  if ($recursive)
161  {
162  $file_list = array_merge($file_list, dol_dir_list($path."/".$file, $types, $recursive, $filter, $excludefilter, $sortcriteria, $sortorder, $mode, $nohook, ($relativename!=''?$relativename.'/':'').$file));
163  }
164  }
165  else if (! $isdir && (($types == "files") || ($types == "all")))
166  {
167  // Add file into file_list array
168  if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file);
169  if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file);
170 
171  if (! $filter || preg_match('/'.$filter.'/i',$file)) // We do not search key $filter into $path, only into $file
172  {
173  preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg);
174  $level1name=(isset($reg[1])?$reg[1]:'');
175  $file_list[] = array(
176  "name" => $file,
177  "path" => $path,
178  "level1name" => $level1name,
179  "relativename" => ($relativename?$relativename.'/':'').$file,
180  "fullname" => $path.'/'.$file,
181  "date" => $filedate,
182  "size" => $filesize,
183  "type" => 'file'
184  );
185  }
186  }
187  }
188  }
189  closedir($dir);
190 
191  // Obtain a list of columns
192  if (! empty($sortcriteria))
193  {
194  $myarray=array();
195  foreach ($file_list as $key => $row)
196  {
197  $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:'');
198  }
199  // Sort the data
200  if ($sortorder) array_multisort($myarray, $sortorder, $file_list);
201  }
202  }
203  }
204 
205  if (is_object($hookmanager) && is_array($hookmanager->resArray)) $file_list = array_merge($file_list, $hookmanager->resArray);
206 
207  return $file_list;
208 }
209 
210 
224 function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0)
225 {
226  global $conf, $db;
227 
228  $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";
229  if ($mode) $sql.=", description";
230  $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files";
231  $sql.=" WHERE filepath = '".$db->escape($path)."'";
232  $sql.=" AND entity = ".$conf->entity;
233 
234  $resql = $db->query($sql);
235  if ($resql)
236  {
237  $file_list=array();
238  $num = $db->num_rows($resql);
239  $i = 0;
240  while ($i < $num)
241  {
242  $obj = $db->fetch_object($resql);
243  if ($obj)
244  {
245  preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg);
246  $level1name=(isset($reg[1])?$reg[1]:'');
247  $file_list[] = array(
248  "rowid" => $obj->rowid,
249  "label" => $obj->label, // md5
250  "name" => $obj->filename,
251  "path" => DOL_DATA_ROOT.'/'.$obj->filepath,
252  "level1name" => $level1name,
253  "fullname" => DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,
254  "fullpath_orig" => $obj->fullpath_orig,
255  "date_c" => $db->jdate($obj->date_c),
256  "date_m" => $db->jdate($obj->date_m),
257  "type" => 'file',
258  "keywords" => $obj->keywords,
259  "cover" => $obj->cover,
260  "position" => (int) $obj->position,
261  "acl" => $obj->acl
262  );
263  }
264  $i++;
265  }
266 
267  // Obtain a list of columns
268  if (! empty($sortcriteria))
269  {
270  $myarray=array();
271  foreach ($file_list as $key => $row)
272  {
273  $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:'');
274  }
275  // Sort the data
276  if ($sortorder) array_multisort($myarray, $sortorder, $file_list);
277  }
278 
279  return $file_list;
280  }
281  else
282  {
283  dol_print_error($db);
284  return array();
285  }
286 }
287 
288 
297 function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir)
298 {
299  global $db, $user;
300 
301  $filearrayindatabase = dol_dir_list_in_database($relativedir, '', null, 'name', SORT_ASC);
302 
303  //var_dump($filearray);
304  //var_dump($filearrayindatabase);
305 
306  // Complete filearray with properties found into $filearrayindatabase
307  foreach($filearray as $key => $val)
308  {
309  $found=0;
310  // Search if it exists into $filearrayindatabase
311  foreach($filearrayindatabase as $key2 => $val2)
312  {
313  if ($filearrayindatabase[$key2]['name'] == $filearray[$key]['name'])
314  {
315  $filearray[$key]['position_name']=($filearrayindatabase[$key2]['position']?$filearrayindatabase[$key2]['position']:'0').'_'.$filearrayindatabase[$key2]['name'];
316  $filearray[$key]['position']=$filearrayindatabase[$key2]['position'];
317  $filearray[$key]['cover']=$filearrayindatabase[$key2]['cover'];
318  $filearray[$key]['acl']=$filearrayindatabase[$key2]['acl'];
319  $filearray[$key]['rowid']=$filearrayindatabase[$key2]['rowid'];
320  $filearray[$key]['label']=$filearrayindatabase[$key2]['label'];
321  $found=1;
322  break;
323  }
324  }
325 
326  if (! $found) // This happen in transition toward version 6, or if files were added manually into os dir.
327  {
328  $filearray[$key]['position']='999999'; // File not indexed are at end. So if we add a file, it will not replace an existing position
329  $filearray[$key]['cover']=0;
330  $filearray[$key]['acl']='';
331 
332  $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filearray[$key]['fullname']);
333  if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file
334  {
335  dol_syslog("list_of_documents We found a file called '".$filearray[$key]['name']."' not indexed into database. We add it");
336  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
337  $ecmfile=new EcmFiles($db);
338 
339  // Add entry into database
340  $filename = basename($rel_filename);
341  $rel_dir = dirname($rel_filename);
342  $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
343  $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
344 
345  $ecmfile->filepath = $rel_dir;
346  $ecmfile->filename = $filename;
347  $ecmfile->label = md5_file(dol_osencode($filearray[$key]['fullname'])); // $destfile is a full path to file
348  $ecmfile->fullpath_orig = $filearray[$key]['fullname'];
349  $ecmfile->gen_or_uploaded = 'unknown';
350  $ecmfile->description = ''; // indexed content
351  $ecmfile->keyword = ''; // keyword content
352  $result = $ecmfile->create($user);
353  if ($result < 0)
354  {
355  setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
356  }
357  else
358  {
359  $filearray[$key]['rowid']=$result;
360  }
361  }
362  else
363  {
364  $filearray[$key]['rowid']=0; // Should not happened
365  }
366  }
367  }
368 
369  /*var_dump($filearray);*/
370 }
371 
372 
380 function dol_compare_file($a, $b)
381 {
382  global $sortorder;
383  global $sortfield;
384 
385  $sortorder=strtoupper($sortorder);
386 
387  if ($sortorder == 'ASC') { $retup=-1; $retdown=1; }
388  else { $retup=1; $retdown=-1; }
389 
390  if ($sortfield == 'name')
391  {
392  if ($a->name == $b->name) return 0;
393  return ($a->name < $b->name) ? $retup : $retdown;
394  }
395  if ($sortfield == 'date')
396  {
397  if ($a->date == $b->date) return 0;
398  return ($a->date < $b->date) ? $retup : $retdown;
399  }
400  if ($sortfield == 'size')
401  {
402  if ($a->size == $b->size) return 0;
403  return ($a->size < $b->size) ? $retup : $retdown;
404  }
405 }
406 
407 
414 function dol_is_dir($folder)
415 {
416  $newfolder=dol_osencode($folder);
417  if (is_dir($newfolder)) return true;
418  else return false;
419 }
420 
427 function dol_is_file($pathoffile)
428 {
429  $newpathoffile=dol_osencode($pathoffile);
430  return is_file($newpathoffile);
431 }
432 
439 function dol_is_url($url)
440 {
441  $tmpprot=array('file','http','https','ftp','zlib','data','ssh','ssh2','ogg','expect');
442  foreach($tmpprot as $prot)
443  {
444  if (preg_match('/^'.$prot.':/i',$url)) return true;
445  }
446  return false;
447 }
448 
455 function dol_dir_is_emtpy($folder)
456 {
457  $newfolder=dol_osencode($folder);
458  if (is_dir($newfolder))
459  {
460  $handle = opendir($newfolder);
461  $folder_content = '';
462  while ((gettype($name = readdir($handle)) != "boolean"))
463  {
464  $name_array[] = $name;
465  }
466  foreach($name_array as $temp) $folder_content .= $temp;
467 
468  closedir($handle);
469 
470  if ($folder_content == "...") return true;
471  else return false;
472  }
473  else
474  return true; // Dir does not exists
475 }
476 
484 function dol_count_nb_of_line($file)
485 {
486  $nb=0;
487 
488  $newfile=dol_osencode($file);
489  //print 'x'.$file;
490  $fp=fopen($newfile,'r');
491  if ($fp)
492  {
493  while (!feof($fp))
494  {
495  $line=fgets($fp);
496  // 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.
497  if (! $line === false) $nb++;
498  }
499  fclose($fp);
500  }
501  else
502  {
503  $nb=-1;
504  }
505 
506  return $nb;
507 }
508 
509 
516 function dol_filesize($pathoffile)
517 {
518  $newpathoffile=dol_osencode($pathoffile);
519  return filesize($newpathoffile);
520 }
521 
528 function dol_filemtime($pathoffile)
529 {
530  $newpathoffile=dol_osencode($pathoffile);
531  return @filemtime($newpathoffile); // @Is to avoid errors if files does not exists
532 }
533 
545 function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
546 {
547  global $conf;
548 
549  dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase);
550 
551  if (empty($srcfile)) return -1;
552  if (empty($destfile)) $destfile=$srcfile;
553 
554  $destexists=dol_is_file($destfile);
555  if (($destfile != $srcfile) && $destexists) return 0;
556 
557  $tmpdestfile=$destfile.'.tmp';
558 
559  $newpathofsrcfile=dol_osencode($srcfile);
560  $newpathoftmpdestfile=dol_osencode($tmpdestfile);
561  $newpathofdestfile=dol_osencode($destfile);
562  $newdirdestfile=dirname($newpathofdestfile);
563 
564  if ($destexists && ! is_writable($newpathofdestfile))
565  {
566  dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to overwrite target file", LOG_WARNING);
567  return -1;
568  }
569  if (! is_writable($newdirdestfile))
570  {
571  dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING);
572  return -2;
573  }
574 
575  dol_delete_file($tmpdestfile);
576 
577  // Create $newpathoftmpdestfile from $newpathofsrcfile
578  $content=file_get_contents($newpathofsrcfile, 'r');
579 
580  $content = make_substitutions($content, $arrayreplacement, null);
581 
582  file_put_contents($newpathoftmpdestfile, $content);
583  @chmod($newpathoftmpdestfile, octdec($newmask));
584 
585  // Rename
586  $result=dol_move($newpathoftmpdestfile, $newpathofdestfile, $newmask, (($destfile == $srcfile)?1:0), 0, $indexdatabase);
587  if (! $result)
588  {
589  dol_syslog("files.lib.php::dolReplaceInFile failed to move tmp file to final dest", LOG_WARNING);
590  return -3;
591  }
592  if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
593  if (empty($newmask)) // This should no happen
594  {
595  dol_syslog("Warning: dolReplaceInFile called with empty value for newmask and no default value defined", LOG_WARNING);
596  $newmask='0664';
597  }
598 
599  @chmod($newpathofdestfile, octdec($newmask));
600 
601  return 1;
602 }
603 
615 function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
616 {
617  // TODO
618 
619 }
620 
631 function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
632 {
633  global $conf;
634 
635  dol_syslog("files.lib.php::dol_copy srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwriteifexists=".$overwriteifexists);
636 
637  if (empty($srcfile) || empty($destfile)) return -1;
638 
639  $destexists=dol_is_file($destfile);
640  if (! $overwriteifexists && $destexists) return 0;
641 
642  $newpathofsrcfile=dol_osencode($srcfile);
643  $newpathofdestfile=dol_osencode($destfile);
644  $newdirdestfile=dirname($newpathofdestfile);
645 
646  if ($destexists && ! is_writable($newpathofdestfile))
647  {
648  dol_syslog("files.lib.php::dol_copy failed Permission denied to overwrite target file", LOG_WARNING);
649  return -1;
650  }
651  if (! is_writable($newdirdestfile))
652  {
653  dol_syslog("files.lib.php::dol_copy failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING);
654  return -2;
655  }
656  // Copy with overwriting if exists
657  $result=@copy($newpathofsrcfile, $newpathofdestfile);
658  //$result=copy($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @
659  if (! $result)
660  {
661  dol_syslog("files.lib.php::dol_copy failed to copy", LOG_WARNING);
662  return -3;
663  }
664  if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
665  if (empty($newmask)) // This should no happen
666  {
667  dol_syslog("Warning: dol_copy called with empty value for newmask and no default value defined", LOG_WARNING);
668  $newmask='0664';
669  }
670 
671  @chmod($newpathofdestfile, octdec($newmask));
672 
673  return 1;
674 }
675 
687 function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null)
688 {
689  global $conf;
690 
691  $result=0;
692 
693  dol_syslog("files.lib.php::dolCopyDir srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwriteifexists=".$overwriteifexists);
694 
695  if (empty($srcfile) || empty($destfile)) return -1;
696 
697  $destexists=dol_is_dir($destfile);
698  //if (! $overwriteifexists && $destexists) return 0; // The overwriteifexists is for files only, so propagated to dol_copy only.
699 
700  if (! $destexists)
701  {
702  // We must set mask just before creating dir, becaause it can be set differently by dol_copy
703  umask(0);
704  $dirmaskdec=octdec($newmask);
705  if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK);
706  $dirmaskdec |= octdec('0200'); // Set w bit required to be able to create content for recursive subdirs files
707  dol_mkdir($destfile, '', decoct($dirmaskdec));
708  }
709 
710  $ossrcfile=dol_osencode($srcfile);
711  $osdestfile=dol_osencode($destfile);
712 
713  // Recursive function to copy all subdirectories and contents:
714  if (is_dir($ossrcfile))
715  {
716  $dir_handle=opendir($ossrcfile);
717  while ($file=readdir($dir_handle))
718  {
719  if ($file != "." && $file != ".." && ! is_link($ossrcfile."/".$file))
720  {
721  if (is_dir($ossrcfile."/".$file))
722  {
723  //var_dump("xxx dolCopyDir $srcfile/$file, $destfile/$file, $newmask, $overwriteifexists");
724  $tmpresult=dolCopyDir($srcfile."/".$file, $destfile."/".$file, $newmask, $overwriteifexists, $arrayreplacement);
725  }
726  else
727  {
728  $newfile = $file;
729  // Replace destination filename with a new one
730  if (is_array($arrayreplacement))
731  {
732  foreach($arrayreplacement as $key => $val)
733  {
734  $newfile = str_replace($key, $val, $newfile);
735  }
736  }
737  $tmpresult=dol_copy($srcfile."/".$file, $destfile."/".$newfile, $newmask, $overwriteifexists);
738  }
739  // Set result
740  if ($result > 0 && $tmpresult >= 0)
741  {
742  // Do nothing, so we don't set result to 0 if tmpresult is 0 and result was success in a previous pass
743  }
744  else
745  {
746  $result=$tmpresult;
747  }
748  if ($result < 0) break;
749 
750  }
751  }
752  closedir($dir_handle);
753  }
754  else
755  {
756  // Source directory does not exists
757  $result = -2;
758  }
759 
760  return $result;
761 }
762 
763 
780 function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1)
781 {
782  global $user, $db, $conf;
783  $result=false;
784 
785  dol_syslog("files.lib.php::dol_move srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." overwritifexists=".$overwriteifexists);
786  $srcexists=dol_is_file($srcfile);
787  $destexists=dol_is_file($destfile);
788 
789  if (! $srcexists)
790  {
791  dol_syslog("files.lib.php::dol_move srcfile does not exists. we ignore the move request.");
792  return false;
793  }
794 
795  if ($overwriteifexists || ! $destexists)
796  {
797  $newpathofsrcfile=dol_osencode($srcfile);
798  $newpathofdestfile=dol_osencode($destfile);
799 
800  // Check virus
801  $testvirusarray=array();
802  if ($testvirus)
803  {
804  $testvirusarray=dolCheckVirus($newpathofsrcfile);
805  if (count($testvirusarray))
806  {
807  dol_syslog("files.lib.php::dol_move canceled because a virus was found into source file. we ignore the move request.", LOG_WARNING);
808  return false;
809  }
810  }
811 
812  $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @
813  if (! $result)
814  {
815  if ($destexists)
816  {
817  dol_syslog("files.lib.php::dol_move Failed. We try to delete target first and move after.", LOG_WARNING);
818  // We force delete and try again. Rename function sometimes fails to replace dest file with some windows NTFS partitions.
819  dol_delete_file($destfile);
820  $result=@rename($newpathofsrcfile, $newpathofdestfile); // To see errors, remove @
821  }
822  else dol_syslog("files.lib.php::dol_move Failed.", LOG_WARNING);
823  }
824 
825  // Move ok
826  if ($result && $indexdatabase)
827  {
828  // Rename entry into ecm database
829  $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile);
830  $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile);
831  if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file
832  {
833  $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore);
834  $rel_filetorenameafter = preg_replace('/^[\\/]/', '', $rel_filetorenameafter);
835  //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter);
836 
837  dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG);
838  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
839 
840  $ecmfiletarget=new EcmFiles($db);
841  $resultecmtarget = $ecmfiletarget->fetch(0, '', $rel_filetorenameafter);
842  if ($resultecmtarget > 0) // An entry for target name already exists for target, we delete it, a new one will be created.
843  {
844  $ecmfiletarget->delete($user);
845  }
846 
847  $ecmfile=new EcmFiles($db);
848  $resultecm = $ecmfile->fetch(0, '', $rel_filetorenamebefore);
849  if ($resultecm > 0) // If an entry was found for src file, we use it to move entry
850  {
851  $filename = basename($rel_filetorenameafter);
852  $rel_dir = dirname($rel_filetorenameafter);
853  $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
854  $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
855 
856  $ecmfile->filepath = $rel_dir;
857  $ecmfile->filename = $filename;
858  $resultecm = $ecmfile->update($user);
859  }
860  elseif ($resultecm == 0) // If no entry were found for src files, create/update target file
861  {
862  $filename = basename($rel_filetorenameafter);
863  $rel_dir = dirname($rel_filetorenameafter);
864  $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
865  $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
866 
867  $ecmfile->filepath = $rel_dir;
868  $ecmfile->filename = $filename;
869  $ecmfile->label = md5_file(dol_osencode($destfile)); // $destfile is a full path to file
870  $ecmfile->fullpath_orig = $srcfile;
871  $ecmfile->gen_or_uploaded = 'unknown';
872  $ecmfile->description = ''; // indexed content
873  $ecmfile->keyword = ''; // keyword content
874  $resultecm = $ecmfile->create($user);
875  if ($resultecm < 0)
876  {
877  setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
878  }
879  }
880  elseif ($resultecm < 0)
881  {
882  setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
883  }
884 
885  if ($resultecm > 0) $result=true;
886  else $result = false;
887  }
888  }
889 
890  if (empty($newmask)) $newmask=empty($conf->global->MAIN_UMASK)?'0755':$conf->global->MAIN_UMASK;
891  $newmaskdec=octdec($newmask);
892  // Currently method is restricted to files (dol_delete_files previously used is for files, and mask usage if for files too)
893  // to allow mask usage for dir, we shoul introduce a new param "isdir" to 1 to complete newmask like this
894  // if ($isdir) $newmaskdec |= octdec('0111'); // Set x bit required for directories
895  @chmod($newpathofdestfile, $newmaskdec);
896  }
897 
898  return $result;
899 }
900 
908 function dol_unescapefile($filename)
909 {
910  // Remove path information and dots around the filename, to prevent uploading
911  // into different directories or replacing hidden system files.
912  // Also remove control characters and spaces (\x00..\x20) around the filename:
913  return trim(basename($filename), ".\x00..\x20");
914 }
915 
916 
923 function dolCheckVirus($src_file)
924 {
925  global $conf;
926 
927  if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND))
928  {
929  if (! class_exists('AntiVir')) {
930  require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php';
931  }
932  $antivir=new AntiVir($db);
933  $result = $antivir->dol_avscan_file($src_file);
934  if ($result < 0) // If virus or error, we stop here
935  {
936  $reterrors=$antivir->errors;
937  return $reterrors;
938  }
939  }
940  return array();
941 }
942 
943 
962 function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile')
963 {
964  global $conf, $db, $user, $langs;
965  global $object, $hookmanager;
966 
967  $reshook=0;
968  $file_name = $dest_file;
969 
970  if (empty($nohook))
971  {
972  $reshook=$hookmanager->initHooks(array('fileslib'));
973 
974  $parameters=array('dest_file' => $dest_file, 'src_file' => $src_file, 'file_name' => $file_name, 'varfiles' => $varfiles, 'allowoverwrite' => $allowoverwrite);
975  $reshook=$hookmanager->executeHooks('moveUploadedFile', $parameters, $object);
976  }
977 
978  if (empty($reshook))
979  {
980  // If an upload error has been reported
981  if ($uploaderrorcode)
982  {
983  switch($uploaderrorcode)
984  {
985  case UPLOAD_ERR_INI_SIZE: // 1
986  return 'ErrorFileSizeTooLarge';
987  break;
988  case UPLOAD_ERR_FORM_SIZE: // 2
989  return 'ErrorFileSizeTooLarge';
990  break;
991  case UPLOAD_ERR_PARTIAL: // 3
992  return 'ErrorPartialFile';
993  break;
994  case UPLOAD_ERR_NO_TMP_DIR: //
995  return 'ErrorNoTmpDir';
996  break;
997  case UPLOAD_ERR_CANT_WRITE:
998  return 'ErrorFailedToWriteInDir';
999  break;
1000  case UPLOAD_ERR_EXTENSION:
1001  return 'ErrorUploadBlockedByAddon';
1002  break;
1003  default:
1004  break;
1005  }
1006  }
1007 
1008  // If we need to make a virus scan
1009  if (empty($disablevirusscan) && file_exists($src_file))
1010  {
1011  $checkvirusarray=dolCheckVirus($src_file);
1012  if (count($checkvirusarray))
1013  {
1014  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);
1015  return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray);
1016  }
1017  }
1018 
1019  // Security:
1020  // Disallow file with some extensions. We rename them.
1021  // Because if we put the documents directory into a directory inside web root (very bad), this allows to execute on demand arbitrary code.
1022  if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED))
1023  {
1024  $file_name.= '.noexe';
1025  }
1026 
1027  // Security:
1028  // We refuse cache files/dirs, upload using .. and pipes into filenames.
1029  if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file))
1030  {
1031  dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
1032  return -1;
1033  }
1034 
1035  // Security:
1036  // On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers.
1037  if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file))
1038  {
1039  dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
1040  return -2;
1041  }
1042  }
1043 
1044  if ($reshook < 0) // At least one blocking error returned by one hook
1045  {
1046  $errmsg = join(',', $hookmanager->errors);
1047  if (empty($errmsg)) $errmsg = 'ErrorReturnedBySomeHooks'; // Should not occurs. Added if hook is bugged and does not set ->errors when there is error.
1048  return $errmsg;
1049  }
1050  elseif (empty($reshook))
1051  {
1052  // The file functions must be in OS filesystem encoding.
1053  $src_file_osencoded=dol_osencode($src_file);
1054  $file_name_osencoded=dol_osencode($file_name);
1055 
1056  // Check if destination dir is writable
1057  if (! is_writable(dirname($file_name_osencoded)))
1058  {
1059  dol_syslog("Files.lib::dol_move_uploaded_file Dir ".dirname($file_name_osencoded)." is not writable. Return 'ErrorDirNotWritable'", LOG_WARNING);
1060  return 'ErrorDirNotWritable';
1061  }
1062 
1063  // Check if destination file already exists
1064  if (! $allowoverwrite)
1065  {
1066  if (file_exists($file_name_osencoded))
1067  {
1068  dol_syslog("Files.lib::dol_move_uploaded_file File ".$file_name." already exists. Return 'ErrorFileAlreadyExists'", LOG_WARNING);
1069  return 'ErrorFileAlreadyExists';
1070  }
1071  }
1072 
1073  // Move file
1074  $return=move_uploaded_file($src_file_osencoded, $file_name_osencoded);
1075  if ($return)
1076  {
1077  if (! empty($conf->global->MAIN_UMASK)) @chmod($file_name_osencoded, octdec($conf->global->MAIN_UMASK));
1078  dol_syslog("Files.lib::dol_move_uploaded_file Success to move ".$src_file." to ".$file_name." - Umask=".$conf->global->MAIN_UMASK, LOG_DEBUG);
1079  return 1; // Success
1080  }
1081  else
1082  {
1083  dol_syslog("Files.lib::dol_move_uploaded_file Failed to move ".$src_file." to ".$file_name, LOG_ERR);
1084  return -3; // Unknown error
1085  }
1086  }
1087 
1088  return 1; // Success
1089 }
1090 
1103 function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=null)
1104 {
1105  global $db, $conf, $user, $langs;
1106  global $hookmanager;
1107 
1108  $langs->load("other");
1109  $langs->load("errors");
1110 
1111  dol_syslog("dol_delete_file file=".$file." disableglob=".$disableglob." nophperrors=".$nophperrors." nohook=".$nohook);
1112 
1113  // Security:
1114  // We refuse transversal using .. and pipes into filenames.
1115  if (preg_match('/\.\./',$file) || preg_match('/[<>|]/',$file))
1116  {
1117  dol_syslog("Refused to delete file ".$file, LOG_WARNING);
1118  return False;
1119  }
1120 
1121  if (empty($nohook))
1122  {
1123  $hookmanager->initHooks(array('fileslib'));
1124 
1125  $parameters=array(
1126  'GET' => $_GET,
1127  'file' => $file,
1128  'disableglob'=> $disableglob,
1129  'nophperrors' => $nophperrors
1130  );
1131  $reshook=$hookmanager->executeHooks('deleteFile', $parameters, $object);
1132  }
1133 
1134  if (empty($nohook) && $reshook != 0) // reshook = 0 to do standard actions, 1 = ok, -1 = ko
1135  {
1136  if ($reshook < 0) return false;
1137  return true;
1138  }
1139  else
1140  {
1141  $error=0;
1142 
1143  //print "x".$file." ".$disableglob;exit;
1144  $file_osencoded=dol_osencode($file); // New filename encoded in OS filesystem encoding charset
1145  if (empty($disableglob) && ! empty($file_osencoded))
1146  {
1147  $ok=true;
1148  $globencoded=str_replace('[','\[',$file_osencoded);
1149  $globencoded=str_replace(']','\]',$globencoded);
1150  $listofdir=glob($globencoded);
1151  if (! empty($listofdir) && is_array($listofdir))
1152  {
1153  foreach ($listofdir as $filename)
1154  {
1155  if ($nophperrors) $ok=@unlink($filename);
1156  else $ok=unlink($filename);
1157  if ($ok)
1158  {
1159  dol_syslog("Removed file ".$filename, LOG_DEBUG);
1160 
1161  // Delete entry into ecm database
1162  $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename);
1163  if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file
1164  {
1165  $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete);
1166 
1167  dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG);
1168  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1169  $ecmfile=new EcmFiles($db);
1170  $result = $ecmfile->fetch(0, '', $rel_filetodelete);
1171  if ($result >= 0 && $ecmfile->id > 0)
1172  {
1173  $result = $ecmfile->delete($user);
1174  }
1175  if ($result < 0)
1176  {
1177  setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
1178  }
1179  }
1180  }
1181  else dol_syslog("Failed to remove file ".$filename, LOG_WARNING);
1182  // TODO Failure to remove can be because file was already removed or because of permission
1183  // If error because of not exists, we must should return true and we should return false if this is a permission problem
1184  }
1185  }
1186  else dol_syslog("No files to delete found", LOG_DEBUG);
1187  }
1188  else
1189  {
1190  $ok=false;
1191  if ($nophperrors) $ok=@unlink($file_osencoded);
1192  else $ok=unlink($file_osencoded);
1193  if ($ok) dol_syslog("Removed file ".$file_osencoded, LOG_DEBUG);
1194  else dol_syslog("Failed to remove file ".$file_osencoded, LOG_WARNING);
1195  }
1196 
1197  return $ok;
1198  }
1199 }
1200 
1210 function dol_delete_dir($dir,$nophperrors=0)
1211 {
1212  // Security:
1213  // We refuse transversal using .. and pipes into filenames.
1214  if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir))
1215  {
1216  dol_syslog("Refused to delete dir ".$dir, LOG_WARNING);
1217  return False;
1218  }
1219 
1220  $dir_osencoded=dol_osencode($dir);
1221  return ($nophperrors?@rmdir($dir_osencoded):rmdir($dir_osencoded));
1222 }
1223 
1234 function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
1235 {
1236  dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir,LOG_DEBUG);
1237  if (dol_is_dir($dir))
1238  {
1239  $dir_osencoded=dol_osencode($dir);
1240  if ($handle = opendir("$dir_osencoded"))
1241  {
1242  while (false !== ($item = readdir($handle)))
1243  {
1244  if (! utf8_check($item)) $item=utf8_encode($item); // should be useless
1245 
1246  if ($item != "." && $item != "..")
1247  {
1248  if (is_dir(dol_osencode("$dir/$item")) && ! is_link(dol_osencode("$dir/$item")))
1249  {
1250  $count=dol_delete_dir_recursive("$dir/$item", $count, $nophperrors, 0, $countdeleted);
1251  }
1252  else
1253  {
1254  $result=dol_delete_file("$dir/$item", 1, $nophperrors);
1255  $count++;
1256  if ($result) $countdeleted++;
1257  }
1258  }
1259  }
1260  closedir($handle);
1261 
1262  if (empty($onlysub))
1263  {
1264  $result=dol_delete_dir($dir, $nophperrors);
1265  $count++;
1266  if ($result) $countdeleted++;
1267  }
1268  }
1269  }
1270 
1271  return $count;
1272 }
1273 
1274 
1283 function dol_delete_preview($object)
1284 {
1285  global $langs,$conf;
1286 
1287  // Define parent dir of elements
1288  $element = $object->element;
1289 
1290  if ($object->element == 'order_supplier') $dir = $conf->fournisseur->commande->dir_output;
1291  elseif ($object->element == 'invoice_supplier') $dir = $conf->fournisseur->facture->dir_output;
1292  elseif ($object->element == 'project') $dir = $conf->projet->dir_output;
1293  elseif ($object->element == 'shipping') $dir = $conf->expedition->dir_output.'/sending';
1294  elseif ($object->element == 'delivery') $dir = $conf->expedition->dir_output.'/receipt';
1295  elseif ($object->element == 'fichinter') $dir = $conf->ficheinter->dir_output;
1296  else $dir=empty($conf->$element->dir_output)?'':$conf->$element->dir_output;
1297 
1298  if (empty($dir)) return 'ErrorObjectNoSupportedByFunction';
1299 
1300  $refsan = dol_sanitizeFileName($object->ref);
1301  $dir = $dir . "/" . $refsan ;
1302  $filepreviewnew = $dir . "/" . $refsan . ".pdf_preview.png";
1303  $filepreviewnewbis = $dir . "/" . $refsan . ".pdf_preview-0.png";
1304  $filepreviewold = $dir . "/" . $refsan . ".pdf.png";
1305 
1306  // For new preview files
1307  if (file_exists($filepreviewnew) && is_writable($filepreviewnew))
1308  {
1309  if (! dol_delete_file($filepreviewnew,1))
1310  {
1311  $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewnew);
1312  return 0;
1313  }
1314  }
1315  if (file_exists($filepreviewnewbis) && is_writable($filepreviewnewbis))
1316  {
1317  if (! dol_delete_file($filepreviewnewbis,1))
1318  {
1319  $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewnewbis);
1320  return 0;
1321  }
1322  }
1323  // For old preview files
1324  if (file_exists($filepreviewold) && is_writable($filepreviewold))
1325  {
1326  if (! dol_delete_file($filepreviewold,1))
1327  {
1328  $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewold);
1329  return 0;
1330  }
1331  }
1332  else
1333  {
1334  $multiple = $filepreviewold . ".";
1335  for ($i = 0; $i < 20; $i++)
1336  {
1337  $preview = $multiple.$i;
1338 
1339  if (file_exists($preview) && is_writable($preview))
1340  {
1341  if ( ! dol_delete_file($preview,1) )
1342  {
1343  $object->error=$langs->trans("ErrorFailedToOpenFile",$preview);
1344  return 0;
1345  }
1346  }
1347  }
1348  }
1349 
1350  return 1;
1351 }
1352 
1361 function dol_meta_create($object)
1362 {
1363  global $conf;
1364 
1365  // Create meta file
1366  if (empty($conf->global->MAIN_DOC_CREATE_METAFILE)) return 0; // By default, no metafile.
1367 
1368  // Define parent dir of elements
1369  $element=$object->element;
1370 
1371  if ($object->element == 'order_supplier') $dir = $conf->fournisseur->dir_output.'/commande';
1372  elseif ($object->element == 'invoice_supplier') $dir = $conf->fournisseur->dir_output.'/facture';
1373  elseif ($object->element == 'project') $dir = $conf->projet->dir_output;
1374  elseif ($object->element == 'shipping') $dir = $conf->expedition->dir_output.'/sending';
1375  elseif ($object->element == 'delivery') $dir = $conf->expedition->dir_output.'/receipt';
1376  elseif ($object->element == 'fichinter') $dir = $conf->ficheinter->dir_output;
1377  else $dir=empty($conf->$element->dir_output)?'':$conf->$element->dir_output;
1378 
1379  if ($dir)
1380  {
1381  $object->fetch_thirdparty();
1382 
1383  $objectref = dol_sanitizeFileName($object->ref);
1384  $dir = $dir . "/" . $objectref;
1385  $file = $dir . "/" . $objectref . ".meta";
1386 
1387  if (! is_dir($dir))
1388  {
1389  dol_mkdir($dir);
1390  }
1391 
1392  if (is_dir($dir))
1393  {
1394  $nblignes = count($object->lines);
1395  $client = $object->thirdparty->name . " " . $object->thirdparty->address . " " . $object->thirdparty->zip . " " . $object->thirdparty->town;
1396  $meta = "REFERENCE=\"" . $object->ref . "\"
1397  DATE=\"" . dol_print_date($object->date,'') . "\"
1398  NB_ITEMS=\"" . $nblignes . "\"
1399  CLIENT=\"" . $client . "\"
1400  AMOUNT_EXCL_TAX=\"" . $object->total_ht . "\"
1401  AMOUNT=\"" . $object->total_ttc . "\"\n";
1402 
1403  for ($i = 0 ; $i < $nblignes ; $i++)
1404  {
1405  //Pour les articles
1406  $meta .= "ITEM_" . $i . "_QUANTITY=\"" . $object->lines[$i]->qty . "\"
1407  ITEM_" . $i . "_AMOUNT_WO_TAX=\"" . $object->lines[$i]->total_ht . "\"
1408  ITEM_" . $i . "_VAT=\"" .$object->lines[$i]->tva_tx . "\"
1409  ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n","",nl2br($object->lines[$i]->desc)) . "\"
1410  ";
1411  }
1412  }
1413 
1414  $fp = fopen($file,"w");
1415  fputs($fp,$meta);
1416  fclose($fp);
1417  if (! empty($conf->global->MAIN_UMASK))
1418  @chmod($file, octdec($conf->global->MAIN_UMASK));
1419 
1420  return 1;
1421  }
1422  else
1423  {
1424  dol_syslog('FailedToDetectDirInDolMetaCreateFor'.$object->element, LOG_WARNING);
1425  }
1426 
1427  return 0;
1428 }
1429 
1430 
1431 
1440 function dol_init_file_process($pathtoscan='', $trackid='')
1441 {
1442  $listofpaths=array();
1443  $listofnames=array();
1444  $listofmimes=array();
1445 
1446  if ($pathtoscan)
1447  {
1448  $listoffiles=dol_dir_list($pathtoscan,'files');
1449  foreach($listoffiles as $key => $val)
1450  {
1451  $listofpaths[]=$val['fullname'];
1452  $listofnames[]=$val['name'];
1453  $listofmimes[]=dol_mimetype($val['name']);
1454  }
1455  }
1456  $keytoavoidconflict = empty($trackid)?'':'-'.$trackid;
1457  $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
1458  $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
1459  $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
1460 }
1461 
1462 
1478 function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1)
1479 {
1480  global $db,$user,$conf,$langs;
1481 
1482  $res = 0;
1483 
1484  if (! empty($_FILES[$varfiles])) // For view $_FILES[$varfiles]['error']
1485  {
1486  dol_syslog('dol_add_file_process upload_dir='.$upload_dir.' allowoverwrite='.$allowoverwrite.' donotupdatesession='.$donotupdatesession.' savingdocmask='.$savingdocmask, LOG_DEBUG);
1487  if (dol_mkdir($upload_dir) >= 0)
1488  {
1489  $TFile = $_FILES[$varfiles];
1490  if (!is_array($TFile['name']))
1491  {
1492  foreach ($TFile as $key => &$val)
1493  {
1494  $val = array($val);
1495  }
1496  }
1497 
1498  $nbfile = count($TFile['name']);
1499  $nbok = 0;
1500  for ($i = 0; $i < $nbfile; $i++)
1501  {
1502  // Define $destfull (path to file including filename) and $destfile (only filename)
1503  $destfull=$upload_dir . "/" . $TFile['name'][$i];
1504  $destfile=$TFile['name'][$i];
1505 
1506  if ($savingdocmask)
1507  {
1508  $destfull=$upload_dir . "/" . preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask);
1509  $destfile=preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask);
1510  }
1511 
1512  // dol_sanitizeFileName the file name and lowercase extension
1513  $info = pathinfo($destfull);
1514  $destfull = $info['dirname'].'/'.dol_sanitizeFileName($info['filename'].'.'.strtolower($info['extension']));
1515  $info = pathinfo($destfile);
1516  $destfile = dol_sanitizeFileName($info['filename'].'.'.strtolower($info['extension']));
1517 
1518  $resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destfull, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles);
1519 
1520  if (is_numeric($resupload) && $resupload > 0) // $resupload can be 'ErrorFileAlreadyExists'
1521  {
1522  global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini;
1523 
1524  include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
1525 
1526  // Generate thumbs.
1527  if ($generatethumbs)
1528  {
1529  if (image_format_supported($destfull) == 1)
1530  {
1531  // Create thumbs
1532  // We can't use $object->addThumbs here because there is no $object known
1533 
1534  // Used on logon for example
1535  $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs");
1536  // Create mini thumbs for image (Ratio is near 16/9)
1537  // Used on menu or for setup page for example
1538  $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs");
1539  }
1540  }
1541 
1542  // Update session
1543  if (empty($donotupdatesession))
1544  {
1545  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
1546  $formmail = new FormMail($db);
1547  $formmail->trackid = $trackid;
1548  $formmail->add_attached_files($destfull, $destfile, $TFile['type'][$i]);
1549  }
1550 
1551  // Update table of files
1552  if ($donotupdatesession)
1553  {
1554  $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir);
1555 
1556  if (! preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir
1557  {
1558  $filename = basename($destfile);
1559  $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
1560  $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
1561 
1562  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1563  $ecmfile=new EcmFiles($db);
1564  $ecmfile->filepath = $rel_dir;
1565  $ecmfile->filename = $filename;
1566  $ecmfile->label = md5_file(dol_osencode($destfull)); // MD5 of file content
1567  $ecmfile->fullpath_orig = $TFile['name'][$i];
1568  $ecmfile->gen_or_uploaded = 'uploaded';
1569  $ecmfile->description = ''; // indexed content
1570  $ecmfile->keyword = ''; // keyword content
1571  $result = $ecmfile->create($user);
1572  if ($result < 0)
1573  {
1574  setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings');
1575  }
1576  }
1577  }
1578 
1579  $nbok++;
1580  }
1581  else
1582  {
1583  $langs->load("errors");
1584  if ($resupload < 0) // Unknown error
1585  {
1586  setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors');
1587  }
1588  else if (preg_match('/ErrorFileIsInfectedWithAVirus/',$resupload)) // Files infected by a virus
1589  {
1590  setEventMessages($langs->trans("ErrorFileIsInfectedWithAVirus"), null, 'errors');
1591  }
1592  else // Known error
1593  {
1594  setEventMessages($langs->trans($resupload), null, 'errors');
1595  }
1596  }
1597  }
1598  if ($nbok > 0)
1599  {
1600  $res = 1;
1601  setEventMessages($langs->trans("FileTransferComplete"), null, 'mesgs');
1602  }
1603  }
1604  } elseif ($link) {
1605  require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
1606  $linkObject = new Link($db);
1607  $linkObject->entity = $conf->entity;
1608  $linkObject->url = $link;
1609  $linkObject->objecttype = GETPOST('objecttype', 'alpha');
1610  $linkObject->objectid = GETPOST('objectid', 'int');
1611  $linkObject->label = GETPOST('label', 'alpha');
1612  $res = $linkObject->create($user);
1613  $langs->load('link');
1614  if ($res > 0) {
1615  setEventMessages($langs->trans("LinkComplete"), null, 'mesgs');
1616  } else {
1617  setEventMessages($langs->trans("ErrorFileNotLinked"), null, 'errors');
1618  }
1619  }
1620  else
1621  {
1622  $langs->load("errors");
1623  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("File")), null, 'errors');
1624  }
1625 
1626  return $res;
1627 }
1628 
1629 
1640 function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile=1,$trackid='')
1641 {
1642  global $db,$user,$conf,$langs,$_FILES;
1643 
1644  $keytodelete=$filenb;
1645  $keytodelete--;
1646 
1647  $listofpaths=array();
1648  $listofnames=array();
1649  $listofmimes=array();
1650  $keytoavoidconflict = empty($trackid)?'':'-'.$trackid;
1651  if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
1652  if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
1653  if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
1654 
1655  if ($keytodelete >= 0)
1656  {
1657  $pathtodelete=$listofpaths[$keytodelete];
1658  $filetodelete=$listofnames[$keytodelete];
1659  if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete,1); // The delete of ecm database is inside the function dol_delete_file
1660  else $result=0;
1661  if ($result >= 0)
1662  {
1663  if (empty($donotdeletefile))
1664  {
1665  $langs->load("other");
1666  setEventMessages($langs->trans("FileWasRemoved",$filetodelete), null, 'mesgs');
1667  }
1668  if (empty($donotupdatesession))
1669  {
1670  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
1671  $formmail = new FormMail($db);
1672  $formmail->trackid = $trackid;
1673  $formmail->remove_attached_files($keytodelete);
1674  }
1675  }
1676  }
1677 }
1678 
1688 function dol_convert_file($fileinput, $ext='png', $fileoutput='')
1689 {
1690  global $langs;
1691 
1692  if (class_exists('Imagick'))
1693  {
1694  $image=new Imagick();
1695  try {
1696  $ret = $image->readImage($fileinput);
1697  } catch(Exception $e) {
1698  dol_syslog("Failed to read image using Imagick. Try to install package 'apt-get install ghostscript'.", LOG_WARNING);
1699  return 0;
1700  }
1701  if ($ret)
1702  {
1703  $ret = $image->setImageFormat($ext);
1704  if ($ret)
1705  {
1706  if (empty($fileoutput)) $fileoutput=$fileinput.".".$ext;
1707 
1708  $count = $image->getNumberImages();
1709  $ret = $image->writeImages($fileoutput, true);
1710  if ($ret) return $count;
1711  else return -3;
1712  }
1713  else
1714  {
1715  return -2;
1716  }
1717  }
1718  else
1719  {
1720  return -1;
1721  }
1722  }
1723  else
1724  {
1725  return 0;
1726  }
1727 }
1728 
1729 
1738 function dol_compress_file($inputfile, $outputfile, $mode="gz")
1739 {
1740  $foundhandler=0;
1741 
1742  try
1743  {
1744  $data = implode("", file(dol_osencode($inputfile)));
1745  if ($mode == 'gz') { $foundhandler=1; $compressdata = gzencode($data, 9); }
1746  elseif ($mode == 'bz') { $foundhandler=1; $compressdata = bzcompress($data, 9); }
1747  elseif ($mode == 'zip')
1748  {
1749  if (defined('ODTPHP_PATHTOPCLZIP'))
1750  {
1751  $foundhandler=1;
1752 
1753  include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php';
1754  $archive = new PclZip($outputfile);
1755  $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile));
1756  //$archive->add($inputfile);
1757  return 1;
1758  }
1759  }
1760 
1761  if ($foundhandler)
1762  {
1763  $fp = fopen($outputfile, "w");
1764  fwrite($fp, $compressdata);
1765  fclose($fp);
1766  return 1;
1767  }
1768  else
1769  {
1770  dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR);
1771  return -2;
1772  }
1773  }
1774  catch (Exception $e)
1775  {
1776  global $langs, $errormsg;
1777  $langs->load("errors");
1778  dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
1779  $errormsg=$langs->trans("ErrorFailedToWriteInDir");
1780  return -1;
1781  }
1782 }
1783 
1791 function dol_uncompress($inputfile,$outputdir)
1792 {
1793  global $langs;
1794 
1795  if (defined('ODTPHP_PATHTOPCLZIP'))
1796  {
1797  dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir);
1798  include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php';
1799  $archive = new PclZip($inputfile);
1800  $result=$archive->extract(PCLZIP_OPT_PATH, $outputdir);
1801  //var_dump($result);
1802  if (! is_array($result) && $result <= 0) return array('error'=>$archive->errorInfo(true));
1803  else
1804  {
1805  $ok=1; $errmsg='';
1806  // Loop on each file to check result for unzipping file
1807  foreach($result as $key => $val)
1808  {
1809  if ($val['status'] == 'path_creation_fail')
1810  {
1811  $langs->load("errors");
1812  $ok=0;
1813  $errmsg=$langs->trans("ErrorFailToCreateDir", $val['filename']);
1814  break;
1815  }
1816  }
1817 
1818  if ($ok) return array();
1819  else return array('error'=>$errmsg);
1820  }
1821  }
1822 
1823  if (class_exists('ZipArchive'))
1824  {
1825  dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir);
1826  $zip = new ZipArchive;
1827  $res = $zip->open($inputfile);
1828  if ($res === TRUE)
1829  {
1830  $zip->extractTo($outputdir.'/');
1831  $zip->close();
1832  return array();
1833  }
1834  else
1835  {
1836  return array('error'=>'ErrUnzipFails');
1837  }
1838  }
1839 
1840  return array('error'=>'ErrNoZipEngine');
1841 }
1842 
1843 
1852 function dol_compress_dir($inputdir, $outputfile, $mode="zip")
1853 {
1854  $foundhandler=0;
1855 
1856  dol_syslog("Try to zip dir ".$inputdir." into ".$outputdir." mode=".$mode);
1857 
1858  if (! dol_is_dir(dirname($outputfile)) || ! is_writable(dirname($outputfile)))
1859  {
1860  global $langs, $errormsg;
1861  $langs->load("errors");
1862  $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile);
1863  return -3;
1864  }
1865 
1866  try
1867  {
1868  if ($mode == 'gz') { $foundhandler=0; }
1869  elseif ($mode == 'bz') { $foundhandler=0; }
1870  elseif ($mode == 'zip')
1871  {
1872  /*if (defined('ODTPHP_PATHTOPCLZIP'))
1873  {
1874  $foundhandler=0; // TODO implement this
1875 
1876  include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php';
1877  $archive = new PclZip($outputfile);
1878  $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile));
1879  //$archive->add($inputfile);
1880  return 1;
1881  }
1882  else*/
1883  if (class_exists('ZipArchive'))
1884  {
1885  $foundhandler=1;
1886 
1887  // Initialize archive object
1888  $zip = new ZipArchive();
1889  $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
1890 
1891  // Create recursive directory iterator
1893  $files = new RecursiveIteratorIterator(
1894  new RecursiveDirectoryIterator($inputdir),
1895  RecursiveIteratorIterator::LEAVES_ONLY
1896  );
1897 
1898  foreach ($files as $name => $file)
1899  {
1900  // Skip directories (they would be added automatically)
1901  if (!$file->isDir())
1902  {
1903  // Get real and relative path for current file
1904  $filePath = $file->getRealPath();
1905  $relativePath = substr($filePath, strlen($inputdir) + 1);
1906 
1907  // Add current file to archive
1908  $zip->addFile($filePath, $relativePath);
1909  }
1910  }
1911 
1912  // Zip archive will be created only after closing object
1913  $zip->close();
1914 
1915  return 1;
1916  }
1917  }
1918 
1919  if (! $foundhandler)
1920  {
1921  dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR);
1922  return -2;
1923  }
1924  else
1925  {
1926  return 0;
1927  }
1928  }
1929  catch (Exception $e)
1930  {
1931  global $langs, $errormsg;
1932  $langs->load("errors");
1933  dol_syslog("Failed to open file ".$outputfile, LOG_ERR);
1934  dol_syslog($e->getMessage(), LOG_ERR);
1935  $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile);
1936  return -1;
1937  }
1938 }
1939 
1940 
1941 
1952 function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta|_preview.*\.png)$','^\.'),$nohook=false,$mode='')
1953 {
1954  $tmparray=dol_dir_list($dir,'files',0,$regexfilter,$excludefilter,'date',SORT_DESC,$mode,$nohook);
1955  return $tmparray[0];
1956 }
1957 
1970 function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser='', $refname='', $mode='read')
1971 {
1972  global $conf, $db, $user;
1973  global $dolibarr_main_data_root, $dolibarr_main_document_root_alt;
1974 
1975  if (! is_object($fuser)) $fuser=$user;
1976 
1977  if (empty($modulepart)) return 'ErrorBadParameter';
1978  if (empty($entity))
1979  {
1980  if (empty($conf->multicompany->enabled)) $entity=1;
1981  else $entity=0;
1982  }
1983  dol_syslog('modulepart='.$modulepart.' original_file='.$original_file.' entity='.$entity);
1984  // We define $accessallowed and $sqlprotectagainstexternals
1985  $accessallowed=0;
1986  $sqlprotectagainstexternals='';
1987  $ret=array();
1988 
1989  // Find the subdirectory name as the reference. For exemple original_file='10/myfile.pdf' -> refname='10'
1990  if (empty($refname)) $refname=basename(dirname($original_file)."/");
1991 
1992  $relative_original_file = $original_file;
1993 
1994  // Define possible keys to use for permission check
1995  $lire='lire'; $read='read'; $download='download';
1996  if ($mode == 'write')
1997  {
1998  $lire='creer'; $read='write'; $download='upload';
1999  }
2000 
2001  // Wrapping for miscellaneous medias files
2002  if ($modulepart == 'medias' && !empty($dolibarr_main_data_root))
2003  {
2004  if (empty($entity) || empty($conf->medias->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
2005  $accessallowed=1;
2006  $original_file=$conf->medias->multidir_output[$entity].'/'.$original_file;
2007  }
2008  // Wrapping for *.log files, like when used with url http://.../document.php?modulepart=logs&file=dolibarr.log
2009  elseif ($modulepart == 'logs' && !empty($dolibarr_main_data_root))
2010  {
2011  $accessallowed=($user->admin && basename($original_file) == $original_file && preg_match('/^dolibarr.*\.log$/', basename($original_file)));
2012  $original_file=$dolibarr_main_data_root.'/'.$original_file;
2013  }
2014  // Wrapping for *.zip files, like when used with url http://.../document.php?modulepart=packages&file=module_myfile.zip
2015  elseif ($modulepart == 'packages' && !empty($dolibarr_main_data_root))
2016  {
2017  // Dir for custom dirs
2018  $tmp=explode(',', $dolibarr_main_document_root_alt);
2019  $dirins = $tmp[0];
2020 
2021  $accessallowed=($user->admin && preg_match('/^module_.*\.zip$/', basename($original_file)));
2022  $original_file=$dirins.'/'.$original_file;
2023  }
2024  // Wrapping for some images
2025  elseif (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output))
2026  {
2027  $accessallowed=1;
2028  $original_file=$conf->mycompany->dir_output.'/logos/'.$original_file;
2029  }
2030  // Wrapping for users photos
2031  elseif ($modulepart == 'userphoto' && !empty($conf->user->dir_output))
2032  {
2033  $accessallowed=1;
2034  $original_file=$conf->user->dir_output.'/'.$original_file;
2035  }
2036  // Wrapping for members photos
2037  elseif ($modulepart == 'memberphoto' && !empty($conf->adherent->dir_output))
2038  {
2039  $accessallowed=1;
2040  $original_file=$conf->adherent->dir_output.'/'.$original_file;
2041  }
2042  // Wrapping pour les apercu factures
2043  elseif ($modulepart == 'apercufacture' && !empty($conf->facture->dir_output))
2044  {
2045  if ($fuser->rights->facture->{$lire}) $accessallowed=1;
2046  $original_file=$conf->facture->dir_output.'/'.$original_file;
2047  }
2048  // Wrapping pour les apercu propal
2049  elseif ($modulepart == 'apercupropal' && !empty($conf->propal->dir_output))
2050  {
2051  if ($fuser->rights->propale->{$lire}) $accessallowed=1;
2052  $original_file=$conf->propal->dir_output.'/'.$original_file;
2053  }
2054  // Wrapping pour les apercu commande
2055  elseif ($modulepart == 'apercucommande' && !empty($conf->commande->dir_output))
2056  {
2057  if ($fuser->rights->commande->{$lire}) $accessallowed=1;
2058  $original_file=$conf->commande->dir_output.'/'.$original_file;
2059  }
2060  // Wrapping pour les apercu intervention
2061  elseif (($modulepart == 'apercufichinter' || $modulepart == 'apercuficheinter') && !empty($conf->ficheinter->dir_output))
2062  {
2063  if ($fuser->rights->ficheinter->{$lire}) $accessallowed=1;
2064  $original_file=$conf->ficheinter->dir_output.'/'.$original_file;
2065  }
2066  // Wrapping pour les apercu conat
2067  elseif (($modulepart == 'apercucontract') && !empty($conf->contrat->dir_output))
2068  {
2069  if ($fuser->rights->contrat->{$lire}) $accessallowed=1;
2070  $original_file=$conf->contrat->dir_output.'/'.$original_file;
2071  }
2072  // Wrapping pour les apercu supplier proposal
2073  elseif (($modulepart == 'apercusupplier_proposal' || $modulepart == 'apercusupplier_proposal') && !empty($conf->supplier_proposal->dir_output))
2074  {
2075  if ($fuser->rights->supplier_proposal->{$lire}) $accessallowed=1;
2076  $original_file=$conf->supplier_proposal->dir_output.'/'.$original_file;
2077  }
2078  // Wrapping pour les apercu supplier order
2079  elseif (($modulepart == 'apercusupplier_order' || $modulepart == 'apercusupplier_order') && !empty($conf->fournisseur->commande->dir_output))
2080  {
2081  if ($fuser->rights->fournisseur->commande->{$lire}) $accessallowed=1;
2082  $original_file=$conf->fournisseur->commande->dir_output.'/'.$original_file;
2083  }
2084  // Wrapping pour les apercu supplier invoice
2085  elseif (($modulepart == 'apercusupplier_invoice' || $modulepart == 'apercusupplier_invoice') && !empty($conf->fournisseur->facture->dir_output))
2086  {
2087  if ($fuser->rights->fournisseur->facture->{$lire}) $accessallowed=1;
2088  $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file;
2089  }
2090  // Wrapping pour les apercu supplier invoice
2091  elseif (($modulepart == 'apercuexpensereport') && !empty($conf->expensereport->dir_output))
2092  {
2093  if ($fuser->rights->expensereport->{$lire}) $accessallowed=1;
2094  $original_file=$conf->expensereport->dir_output.'/'.$original_file;
2095  }
2096  // Wrapping pour les images des stats propales
2097  elseif ($modulepart == 'propalstats' && !empty($conf->propal->dir_temp))
2098  {
2099  if ($fuser->rights->propale->{$lire}) $accessallowed=1;
2100  $original_file=$conf->propal->dir_temp.'/'.$original_file;
2101  }
2102  // Wrapping pour les images des stats commandes
2103  elseif ($modulepart == 'orderstats' && !empty($conf->commande->dir_temp))
2104  {
2105  if ($fuser->rights->commande->{$lire}) $accessallowed=1;
2106  $original_file=$conf->commande->dir_temp.'/'.$original_file;
2107  }
2108  elseif ($modulepart == 'orderstatssupplier' && !empty($conf->fournisseur->dir_output))
2109  {
2110  if ($fuser->rights->fournisseur->commande->{$lire}) $accessallowed=1;
2111  $original_file=$conf->fournisseur->commande->dir_temp.'/'.$original_file;
2112  }
2113  // Wrapping pour les images des stats factures
2114  elseif ($modulepart == 'billstats' && !empty($conf->facture->dir_temp))
2115  {
2116  if ($fuser->rights->facture->{$lire}) $accessallowed=1;
2117  $original_file=$conf->facture->dir_temp.'/'.$original_file;
2118  }
2119  elseif ($modulepart == 'billstatssupplier' && !empty($conf->fournisseur->dir_output))
2120  {
2121  if ($fuser->rights->fournisseur->facture->{$lire}) $accessallowed=1;
2122  $original_file=$conf->fournisseur->facture->dir_temp.'/'.$original_file;
2123  }
2124  // Wrapping pour les images des stats expeditions
2125  elseif ($modulepart == 'expeditionstats' && !empty($conf->expedition->dir_temp))
2126  {
2127  if ($fuser->rights->expedition->{$lire}) $accessallowed=1;
2128  $original_file=$conf->expedition->dir_temp.'/'.$original_file;
2129  }
2130  // Wrapping pour les images des stats expeditions
2131  elseif ($modulepart == 'tripsexpensesstats' && !empty($conf->deplacement->dir_temp))
2132  {
2133  if ($fuser->rights->deplacement->{$lire}) $accessallowed=1;
2134  $original_file=$conf->deplacement->dir_temp.'/'.$original_file;
2135  }
2136  // Wrapping pour les images des stats expeditions
2137  elseif ($modulepart == 'memberstats' && !empty($conf->adherent->dir_temp))
2138  {
2139  if ($fuser->rights->adherent->{$lire}) $accessallowed=1;
2140  $original_file=$conf->adherent->dir_temp.'/'.$original_file;
2141  }
2142  // Wrapping pour les images des stats produits
2143  elseif (preg_match('/^productstats_/i',$modulepart) && !empty($conf->product->dir_temp))
2144  {
2145  if ($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) $accessallowed=1;
2146  $original_file=(!empty($conf->product->multidir_temp[$entity])?$conf->product->multidir_temp[$entity]:$conf->service->multidir_temp[$entity]).'/'.$original_file;
2147  }
2148  // Wrapping for taxes
2149  elseif ($modulepart == 'tax' && !empty($conf->tax->dir_output))
2150  {
2151  if ($fuser->rights->tax->charges->{$lire}) $accessallowed=1;
2152  $original_file=$conf->tax->dir_output.'/'.$original_file;
2153  }
2154  // Wrapping for events
2155  elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output))
2156  {
2157  if ($fuser->rights->agenda->myactions->{$read}) $accessallowed=1;
2158  $original_file=$conf->agenda->dir_output.'/'.$original_file;
2159  }
2160  // Wrapping for categories
2161  elseif ($modulepart == 'category' && !empty($conf->categorie->dir_output))
2162  {
2163  if (empty($entity) || empty($conf->categorie->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
2164  if ($fuser->rights->categorie->{$lire}) $accessallowed=1;
2165  $original_file=$conf->categorie->multidir_output[$entity].'/'.$original_file;
2166  }
2167  // Wrapping pour les prelevements
2168  elseif ($modulepart == 'prelevement' && !empty($conf->prelevement->dir_output))
2169  {
2170  if ($fuser->rights->prelevement->bons->{$lire} || preg_match('/^specimen/i',$original_file)) $accessallowed=1;
2171  $original_file=$conf->prelevement->dir_output.'/'.$original_file;
2172  }
2173  // Wrapping pour les graph energie
2174  elseif ($modulepart == 'graph_stock' && !empty($conf->stock->dir_temp))
2175  {
2176  $accessallowed=1;
2177  $original_file=$conf->stock->dir_temp.'/'.$original_file;
2178  }
2179  // Wrapping pour les graph fournisseurs
2180  elseif ($modulepart == 'graph_fourn' && !empty($conf->fournisseur->dir_temp))
2181  {
2182  $accessallowed=1;
2183  $original_file=$conf->fournisseur->dir_temp.'/'.$original_file;
2184  }
2185  // Wrapping pour les graph des produits
2186  elseif ($modulepart == 'graph_product' && !empty($conf->product->dir_temp))
2187  {
2188  $accessallowed=1;
2189  $original_file=$conf->product->multidir_temp[$entity].'/'.$original_file;
2190  }
2191  // Wrapping pour les code barre
2192  elseif ($modulepart == 'barcode')
2193  {
2194  $accessallowed=1;
2195  // If viewimage is called for barcode, we try to output an image on the fly, with no build of file on disk.
2196  //$original_file=$conf->barcode->dir_temp.'/'.$original_file;
2197  $original_file='';
2198  }
2199  // Wrapping pour les icones de background des mailings
2200  elseif ($modulepart == 'iconmailing' && !empty($conf->mailing->dir_temp))
2201  {
2202  $accessallowed=1;
2203  $original_file=$conf->mailing->dir_temp.'/'.$original_file;
2204  }
2205  // Wrapping pour le scanner
2206  elseif ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp))
2207  {
2208  $accessallowed=1;
2209  $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file;
2210  }
2211  // Wrapping pour les images fckeditor
2212  elseif ($modulepart == 'fckeditor' && !empty($conf->fckeditor->dir_output))
2213  {
2214  $accessallowed=1;
2215  $original_file=$conf->fckeditor->dir_output.'/'.$original_file;
2216  }
2217 
2218  // Wrapping for users
2219  else if ($modulepart == 'user' && !empty($conf->user->dir_output))
2220  {
2221  $canreaduser=(! empty($fuser->admin) || $fuser->rights->user->user->{$lire});
2222  if ($fuser->id == (int) $refname) { $canreaduser=1; } // A user can always read its own card
2223  if ($canreaduser || preg_match('/^specimen/i',$original_file))
2224  {
2225  $accessallowed=1;
2226  }
2227  $original_file=$conf->user->dir_output.'/'.$original_file;
2228  }
2229 
2230  // Wrapping for third parties
2231  else if (($modulepart == 'company' || $modulepart == 'societe') && !empty($conf->societe->dir_output))
2232  {
2233  if (empty($entity) || empty($conf->societe->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
2234  if ($fuser->rights->societe->{$lire} || preg_match('/^specimen/i',$original_file))
2235  {
2236  $accessallowed=1;
2237  }
2238  $original_file=$conf->societe->multidir_output[$entity].'/'.$original_file;
2239  $sqlprotectagainstexternals = "SELECT rowid as fk_soc FROM ".MAIN_DB_PREFIX."societe WHERE rowid='".$db->escape($refname)."' AND entity IN (".getEntity('societe').")";
2240  }
2241 
2242  // Wrapping for contact
2243  else if ($modulepart == 'contact' && !empty($conf->societe->dir_output))
2244  {
2245  if (empty($entity) || empty($conf->societe->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
2246  if ($fuser->rights->societe->{$lire})
2247  {
2248  $accessallowed=1;
2249  }
2250  $original_file=$conf->societe->multidir_output[$entity].'/contact/'.$original_file;
2251  }
2252 
2253  // Wrapping for invoices
2254  else if (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output))
2255  {
2256  if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2257  {
2258  $accessallowed=1;
2259  }
2260  $original_file=$conf->facture->dir_output.'/'.$original_file;
2261  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2262  }
2263  // Wrapping for mass actions
2264  else if ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->dir_output))
2265  {
2266  if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i',$original_file))
2267  {
2268  $accessallowed=1;
2269  }
2270  $original_file=$conf->propal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2271  }
2272  else if ($modulepart == 'massfilesarea_orders')
2273  {
2274  if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2275  {
2276  $accessallowed=1;
2277  }
2278  $original_file=$conf->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2279  }
2280  else if ($modulepart == 'massfilesarea_invoices')
2281  {
2282  if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2283  {
2284  $accessallowed=1;
2285  }
2286  $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2287  }
2288  else if ($modulepart == 'massfilesarea_expensereport')
2289  {
2290  if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2291  {
2292  $accessallowed=1;
2293  }
2294  $original_file=$conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2295  }
2296  else if ($modulepart == 'massfilesarea_interventions')
2297  {
2298  if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file))
2299  {
2300  $accessallowed=1;
2301  }
2302  $original_file=$conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2303  }
2304  else if ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->propal->dir_output))
2305  {
2306  if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i',$original_file))
2307  {
2308  $accessallowed=1;
2309  }
2310  $original_file=$conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2311  }
2312  else if ($modulepart == 'massfilesarea_supplier_order')
2313  {
2314  if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2315  {
2316  $accessallowed=1;
2317  }
2318  $original_file=$conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2319  }
2320  else if ($modulepart == 'massfilesarea_supplier_invoice')
2321  {
2322  if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2323  {
2324  $accessallowed=1;
2325  }
2326  $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2327  }
2328  else if ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output))
2329  {
2330  if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file))
2331  {
2332  $accessallowed=1;
2333  }
2334  $original_file=$conf->contrat->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file;
2335  }
2336 
2337  // Wrapping for interventions
2338  else if (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output))
2339  {
2340  if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file))
2341  {
2342  $accessallowed=1;
2343  }
2344  $original_file=$conf->ficheinter->dir_output.'/'.$original_file;
2345  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2346  }
2347 
2348  // Wrapping pour les deplacements et notes de frais
2349  else if ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output))
2350  {
2351  if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i',$original_file))
2352  {
2353  $accessallowed=1;
2354  }
2355  $original_file=$conf->deplacement->dir_output.'/'.$original_file;
2356  //$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2357  }
2358  // Wrapping pour les propales
2359  else if ($modulepart == 'propal' && !empty($conf->propal->dir_output))
2360  {
2361  if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i',$original_file))
2362  {
2363  $accessallowed=1;
2364  }
2365 
2366  $original_file=$conf->propal->dir_output.'/'.$original_file;
2367  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."propal WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2368  }
2369 
2370  // Wrapping pour les commandes
2371  else if (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output))
2372  {
2373  if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2374  {
2375  $accessallowed=1;
2376  }
2377  $original_file=$conf->commande->dir_output.'/'.$original_file;
2378  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2379  }
2380 
2381  // Wrapping pour les projets
2382  else if ($modulepart == 'project' && !empty($conf->projet->dir_output))
2383  {
2384  if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file))
2385  {
2386  $accessallowed=1;
2387  }
2388  $original_file=$conf->projet->dir_output.'/'.$original_file;
2389  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")";
2390  }
2391  else if ($modulepart == 'project_task' && !empty($conf->projet->dir_output))
2392  {
2393  if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file))
2394  {
2395  $accessallowed=1;
2396  }
2397  $original_file=$conf->projet->dir_output.'/'.$original_file;
2398  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")";
2399  }
2400 
2401  // Wrapping pour les commandes fournisseurs
2402  else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output))
2403  {
2404  if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file))
2405  {
2406  $accessallowed=1;
2407  }
2408  $original_file=$conf->fournisseur->commande->dir_output.'/'.$original_file;
2409  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande_fournisseur WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2410  }
2411 
2412  // Wrapping pour les factures fournisseurs
2413  else if (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output))
2414  {
2415  if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2416  {
2417  $accessallowed=1;
2418  }
2419  $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file;
2420  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE facnumber='".$db->escape($refname)."' AND entity=".$conf->entity;
2421  }
2422  // Wrapping pour les rapport de paiements
2423  else if ($modulepart == 'supplier_payment')
2424  {
2425  if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2426  {
2427  $accessallowed=1;
2428  }
2429  $original_file=$conf->fournisseur->payment->dir_output.'/'.$original_file;
2430  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."paiementfournisseur WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2431  }
2432 
2433  // Wrapping pour les rapport de paiements
2434  else if ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output))
2435  {
2436  if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file))
2437  {
2438  $accessallowed=1;
2439  }
2440  if ($fuser->societe_id > 0) $original_file=$conf->facture->dir_output.'/payments/private/'.$fuser->id.'/'.$original_file;
2441  else $original_file=$conf->facture->dir_output.'/payments/'.$original_file;
2442  }
2443 
2444  // Wrapping for accounting exports
2445  else if ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output))
2446  {
2447  if ($fuser->rights->accounting->bind->write || preg_match('/^specimen/i',$original_file))
2448  {
2449  $accessallowed=1;
2450  }
2451  $original_file=$conf->accounting->dir_output.'/'.$original_file;
2452  }
2453 
2454  // Wrapping pour les expedition
2455  else if ($modulepart == 'expedition' && !empty($conf->expedition->dir_output))
2456  {
2457  if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i',$original_file))
2458  {
2459  $accessallowed=1;
2460  }
2461  $original_file=$conf->expedition->dir_output."/sending/".$original_file;
2462  }
2463  // Wrapping pour les bons de livraison
2464  else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output))
2465  {
2466  if ($fuser->rights->expedition->livraison->{$lire} || preg_match('/^specimen/i',$original_file))
2467  {
2468  $accessallowed=1;
2469  }
2470  $original_file=$conf->expedition->dir_output."/receipt/".$original_file;
2471  }
2472 
2473  // Wrapping pour les actions
2474  else if ($modulepart == 'actions' && !empty($conf->agenda->dir_output))
2475  {
2476  if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i',$original_file))
2477  {
2478  $accessallowed=1;
2479  }
2480  $original_file=$conf->agenda->dir_output.'/'.$original_file;
2481  }
2482 
2483  // Wrapping pour les actions
2484  else if ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp))
2485  {
2486  if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i',$original_file))
2487  {
2488  $accessallowed=1;
2489  }
2490  $original_file = $conf->agenda->dir_temp."/".$original_file;
2491  }
2492 
2493  // Wrapping pour les produits et services
2494  else if ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service')
2495  {
2496  if (empty($entity) || (empty($conf->product->multidir_output[$entity]) && empty($conf->service->multidir_output[$entity]))) return array('accessallowed'=>0, 'error'=>'Value entity must be provided');
2497  if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i',$original_file))
2498  {
2499  $accessallowed=1;
2500  }
2501  if (! empty($conf->product->enabled)) $original_file=$conf->product->multidir_output[$entity].'/'.$original_file;
2502  elseif (! empty($conf->service->enabled)) $original_file=$conf->service->multidir_output[$entity].'/'.$original_file;
2503  }
2504 
2505  // Wrapping pour les contrats
2506  else if ($modulepart == 'contract' && !empty($conf->contrat->dir_output))
2507  {
2508  if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file))
2509  {
2510  $accessallowed=1;
2511  }
2512  $original_file=$conf->contrat->dir_output.'/'.$original_file;
2513  $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."contrat WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('contract').")";
2514  }
2515 
2516  // Wrapping pour les dons
2517  else if ($modulepart == 'donation' && !empty($conf->don->dir_output))
2518  {
2519  if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i',$original_file))
2520  {
2521  $accessallowed=1;
2522  }
2523  $original_file=$conf->don->dir_output.'/'.$original_file;
2524  }
2525 
2526  // Wrapping pour les dons
2527  else if ($modulepart == 'dolresource' && !empty($conf->resource->dir_output))
2528  {
2529  if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i',$original_file))
2530  {
2531  $accessallowed=1;
2532  }
2533  $original_file=$conf->resource->dir_output.'/'.$original_file;
2534  }
2535 
2536  // Wrapping pour les remises de cheques
2537  else if ($modulepart == 'remisecheque' && !empty($conf->banque->dir_output))
2538  {
2539  if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i',$original_file))
2540  {
2541  $accessallowed=1;
2542  }
2543 
2544  $original_file=$conf->bank->dir_output.'/checkdeposits/'.$original_file; // original_file should contains relative path so include the get_exdir result
2545  }
2546 
2547  // Wrapping for bank
2548  else if ($modulepart == 'bank' && !empty($conf->bank->dir_output))
2549  {
2550  if ($fuser->rights->banque->{$lire})
2551  {
2552  $accessallowed=1;
2553  }
2554  $original_file=$conf->bank->dir_output.'/'.$original_file;
2555  }
2556 
2557  // Wrapping for export module
2558  else if ($modulepart == 'export' && !empty($conf->export->dir_temp))
2559  {
2560  // Aucun test necessaire car on force le rep de download sur
2561  // le rep export qui est propre a l'utilisateur
2562  $accessallowed=1;
2563  $original_file=$conf->export->dir_temp.'/'.$fuser->id.'/'.$original_file;
2564  }
2565 
2566  // Wrapping for import module
2567  else if ($modulepart == 'import' && !empty($conf->import->dir_temp))
2568  {
2569  $accessallowed=1;
2570  $original_file=$conf->import->dir_temp.'/'.$original_file;
2571  }
2572 
2573  // Wrapping pour l'editeur wysiwyg
2574  else if ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output))
2575  {
2576  $accessallowed=1;
2577  $original_file=$conf->fckeditor->dir_output.'/'.$original_file;
2578  }
2579 
2580  // Wrapping for backups
2581  else if ($modulepart == 'systemtools' && !empty($conf->admin->dir_output))
2582  {
2583  if ($fuser->admin) $accessallowed=1;
2584  $original_file=$conf->admin->dir_output.'/'.$original_file;
2585  }
2586 
2587  // Wrapping for upload file test
2588  else if ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp))
2589  {
2590  if ($fuser->admin) $accessallowed=1;
2591  $original_file=$conf->admin->dir_temp.'/'.$original_file;
2592  }
2593 
2594  // Wrapping pour BitTorrent
2595  else if ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output))
2596  {
2597  $accessallowed=1;
2598  $dir='files';
2599  if (dol_mimetype($original_file) == 'application/x-bittorrent') $dir='torrents';
2600  $original_file=$conf->bittorrent->dir_output.'/'.$dir.'/'.$original_file;
2601  }
2602 
2603  // Wrapping pour Foundation module
2604  else if ($modulepart == 'member' && !empty($conf->adherent->dir_output))
2605  {
2606  if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i',$original_file))
2607  {
2608  $accessallowed=1;
2609  }
2610  $original_file=$conf->adherent->dir_output.'/'.$original_file;
2611  }
2612 
2613  // Wrapping for Scanner
2614  else if ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp))
2615  {
2616  $accessallowed=1;
2617  $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file;
2618  }
2619 
2620  // GENERIC Wrapping
2621  // If modulepart=module_user_temp Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp/iduser
2622  // If modulepart=module_temp Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/temp
2623  // If modulepart=module_user Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart/iduser
2624  // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart
2625  else
2626  {
2627  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.
2628  if ($fuser->admin) $accessallowed=1; // If user is admin
2629 
2630  // Define $accessallowed
2631  if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg))
2632  {
2633  if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported
2634  {
2635  dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2636  exit;
2637  }
2638  if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1;
2639  $original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file;
2640  }
2641  else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg))
2642  {
2643  if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported
2644  {
2645  dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2646  exit;
2647  }
2648  if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1;
2649  $original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file;
2650  }
2651  else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg))
2652  {
2653  if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported
2654  {
2655  dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2656  exit;
2657  }
2658  if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1;
2659  $original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file;
2660  }
2661  else
2662  {
2663  if (empty($conf->$modulepart->dir_output)) // modulepart not supported
2664  {
2665  dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')');
2666  exit;
2667  }
2668 
2669  $perm=GETPOST('perm');
2670  $subperm=GETPOST('subperm');
2671  if ($perm || $subperm)
2672  {
2673  if (($perm && ! $subperm && $fuser->rights->$modulepart->$perm) || ($perm && $subperm && $fuser->rights->$modulepart->$perm->$subperm)) $accessallowed=1;
2674  $original_file=$conf->$modulepart->dir_output.'/'.$original_file;
2675  }
2676  else
2677  {
2678  if ($fuser->rights->$modulepart->{$lire} || $fuser->rights->$modulepart->{$read}) $accessallowed=1;
2679  $original_file=$conf->$modulepart->dir_output.'/'.$original_file;
2680  }
2681  }
2682 
2683  // For modules who wants to manage different levels of permissions for documents
2684  $subPermCategoryConstName = strtoupper($modulepart).'_SUBPERMCATEGORY_FOR_DOCUMENTS';
2685  if (! empty($conf->global->$subPermCategoryConstName))
2686  {
2687  $subPermCategory = $conf->global->$subPermCategoryConstName;
2688  if (! empty($subPermCategory) && (($fuser->rights->$modulepart->$subPermCategory->{$lire}) || ($fuser->rights->$modulepart->$subPermCategory->{$read}) || ($fuser->rights->$modulepart->$subPermCategory->{$download})))
2689  {
2690  $accessallowed=1;
2691  }
2692  }
2693 
2694  // Define $sqlprotectagainstexternals for modules who want to protect access using a SQL query.
2695  $sqlProtectConstName = strtoupper($modulepart).'_SQLPROTECTAGAINSTEXTERNALS_FOR_DOCUMENTS';
2696  if (! empty($conf->global->$sqlProtectConstName)) // If module want to define its own $sqlprotectagainstexternals
2697  {
2698  // Example: mymodule__SQLPROTECTAGAINSTEXTERNALS_FOR_DOCUMENTS = "SELECT fk_soc FROM ".MAIN_DB_PREFIX.$modulepart." WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
2699  eval('$sqlprotectagainstexternals = "'.$conf->global->$sqlProtectConstName.'";');
2700  }
2701  }
2702 
2703  $ret = array(
2704  'accessallowed' => $accessallowed,
2705  'sqlprotectagainstexternals'=>$sqlprotectagainstexternals,
2706  'original_file'=>$original_file
2707  );
2708 
2709  return $ret;
2710 }
2711 
2720 function dol_filecache($directory, $filename, $object)
2721 {
2722  if (! dol_is_dir($directory)) dol_mkdir($directory);
2723  $cachefile = $directory . $filename;
2724  file_put_contents($cachefile, serialize($object), LOCK_EX);
2725  @chmod($cachefile, 0644);
2726 }
2727 
2736 function dol_cache_refresh($directory, $filename, $cachetime)
2737 {
2738  $now = dol_now();
2739  $cachefile = $directory . $filename;
2740  $refresh = !file_exists($cachefile) || ($now-$cachetime) > dol_filemtime($cachefile);
2741  return $refresh;
2742 }
2743 
2751 function dol_readcachefile($directory, $filename)
2752 {
2753  $cachefile = $directory . $filename;
2754  $object = unserialize(file_get_contents($cachefile));
2755  return $object;
2756 }
2757 
2758 
2770 function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathref = '', &$checksumconcat = array())
2771 {
2772  $exclude = 'install';
2773 
2774  foreach ($dir->md5file as $file) // $file is a simpleXMLElement
2775  {
2776  $filename = $path.$file['name'];
2777  $file_list['insignature'][] = $filename;
2778 
2779  //if (preg_match('#'.$exclude.'#', $filename)) continue;
2780 
2781  if (!file_exists($pathref.'/'.$filename))
2782  {
2783  $file_list['missing'][] = array('filename'=>$filename, 'expectedmd5'=>(string) $file);
2784  }
2785  else
2786  {
2787  $md5_local = md5_file($pathref.'/'.$filename);
2788  if ($md5_local != (string) $file) $file_list['updated'][] = array('filename'=>$filename, 'expectedmd5'=>(string) $file, 'md5'=>(string) $md5_local);
2789  $checksumconcat[] = $md5_local;
2790  }
2791  }
2792 
2793  foreach ($dir->dir as $subdir) getFilesUpdated($file_list, $subdir, $path.$subdir['name'].'/', $pathref, $checksumconcat);
2794 
2795  return $file_list;
2796 }
2797 
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
image_format_supported($file)
Return if a filename is file name of a supported image format.
Definition: images.lib.php:38
dol_compare_file($a, $b)
Fast compare of 2 files identified by their properties ->name, ->date and ->size. ...
Definition: files.lib.php:380
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
Copy a file to another file.
Definition: files.lib.php:631
dol_compress_file($inputfile, $outputfile, $mode="gz")
Compress a file.
Definition: files.lib.php:1738
getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path= '', $pathref= '', &$checksumconcat=array())
Function to get list of updated or modified files.
Definition: files.lib.php:2770
Classe permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new For...
dol_unescapefile($filename)
Unescape a file submitted by upload.
Definition: files.lib.php:908
dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:224
dol_cache_refresh($directory, $filename, $cachetime)
Test if Refresh needed.
Definition: files.lib.php:2736
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile')
Make control on an uploaded file from an GUI page and move it to final destination.
Definition: files.lib.php:962
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
if(!GETPOST('transkey')&&!GETPOST('transphrase')) else
View.
Definition: notice.php:43
dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
Make replacement of strings into a file.
Definition: files.lib.php:615
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
completeFileArrayWithDatabaseInfo(&$filearray, $relativedir)
Complete $filearray with data from database.
Definition: files.lib.php:297
if(GETPOST('cancel','alpha')) if(!GETPOST('confirmmassaction','alpha')&&$massaction!= 'presend'&&$massaction!= 'confirm_presend')
Draft customers invoices.
Definition: list.php:147
dol_delete_preview($object)
Delete all preview files linked to object instance.
Definition: files.lib.php:1283
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return mime type of a file.
Class to scan for virus.
dol_remove_file_process($filenb, $donotupdatesession=0, $donotdeletefile=1, $trackid='')
Remove an uploaded file (for example after submitting a new file a mail form).
Definition: files.lib.php:1640
dol_filesize($pathoffile)
Return size of a file.
Definition: files.lib.php:516
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dol_is_dir($folder)
Test if filename is a directory.
Definition: files.lib.php:414
dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser='', $refname='', $mode='read')
Security check when accessing to a document (used by document.php, viewimage.php and webservices) ...
Definition: files.lib.php:1970
dolCheckVirus($src_file)
Check virus into a file.
Definition: files.lib.php:923
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="")
Scan a directory and return a list of files/directories.
Definition: files.lib.php:58
GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NULL, $noreplace=0)
Return value of a param into GET or POST supervariable.
dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null)
Copy a dir to another dir.
Definition: files.lib.php:687
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1)
Move a file into another name.
Definition: files.lib.php:780
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
dol_is_url($url)
Return if path is an URL.
Definition: files.lib.php:439
dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1)
Get and save an upload file (for example after submitting a new file a mail form).
Definition: files.lib.php:1478
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories) ...
Definition: files.lib.php:1234
dol_basename($pathfile)
Make a basename working with all page code (default PHP basenamed fails with cyrillic).
Definition: files.lib.php:35
getEntity($element, $shared=1, $forceentity=null)
Get list of entity id to use.
dol_most_recent_file($dir, $regexfilter='', $excludefilter=array('(\.meta|_preview.*\.png)$','^\.'), $nohook=false, $mode='')
Return file(s) into a directory (by default most recent)
Definition: files.lib.php:1952
dol_now($mode='gmt')
Return date for now.
utf8_check($str)
Check if a string is in UTF8.
dol_count_nb_of_line($file)
Count number of lines in a file.
Definition: files.lib.php:484
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:427
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_uncompress($inputfile, $outputdir)
Uncompress a file.
Definition: files.lib.php:1791
dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
Make replacement of strings into a file.
Definition: files.lib.php:545
dol_init_file_process($pathtoscan='', $trackid='')
Scan a directory and init $_SESSION to manage uploaded files with list of all found files...
Definition: files.lib.php:1440
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:528
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->societe->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1013
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null)
Remove a file or several files with a mask.
Definition: files.lib.php:1103
dol_readcachefile($directory, $filename)
Read object from cachefile.
Definition: files.lib.php:2751
make_substitutions($text, $substitutionarray, $outputlangs=null)
Make substition into a text string, replacing keys with vals from $substitutionarray (oldval=>newval)...
dol_dir_is_emtpy($folder)
Test if a folder is empty.
Definition: files.lib.php:455
dol_convert_file($fileinput, $ext='png', $fileoutput='')
Convert an image file into another format.
Definition: files.lib.php:1688
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
Definition: files.lib.php:1210
Class to manage ECM files.
dol_meta_create($object)
Create a meta file with document file into same directory.
Definition: files.lib.php:1361
dol_filecache($directory, $filename, $object)
Store object in file.
Definition: files.lib.php:2720
vignette($file, $maxWidth=160, $maxHeight=120, $extName='_small', $quality=50, $outdir='thumbs', $targetformat=0)
Create a thumbnail from an image file (Supported extensions are gif, jpg, png and bmp)...
Definition: images.lib.php:352