diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index d04840e2d71..0bef19dde56 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -29,15 +29,15 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; $langs->load("admin"); -$action=GETPOST('action','alpha'); +$action=GETPOST('action', 'alpha'); -$sortfield = GETPOST('sortfield','alpha'); -$sortorder = GETPOST('sortorder','alpha'); -$page = GETPOST('page','int'); +$sortfield = GETPOST('sortfield', 'alpha'); +$sortorder = GETPOST('sortorder', 'alpha'); +$page = GETPOST('page', 'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="date"; if (empty($page) || $page == -1) { $page = 0; } -$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; $offset = $limit * $page; if (! $user->admin) @@ -50,10 +50,20 @@ if (! $user->admin) if ($action == 'delete') { - $file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha')); - $ret=dol_delete_file($file, 1); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + if (preg_match('/^backup\//', GETPOST('urlfile', 'alpha'))) + { + $file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha')); + $ret=dol_delete_file($file, 1); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + } + else + { + $file=$conf->admin->dir_output.'/documents/'.basename(GETPOST('urlfile', 'alpha')); + $ret=dol_delete_file($file, 1); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + } $action=''; } @@ -70,7 +80,7 @@ $type=$db->type; //var_dump($db); $help_url='EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad'; -llxHeader('','',$help_url); +llxHeader('', '', $help_url); ?> trans("Backup"),'','title_setup'); +print load_fiche_titre($langs->trans("Backup"), '', 'title_setup'); //print_barre_liste($langs->trans("Backup"), '', '', '', '', '', $langs->trans("BackupDesc",DOL_DATA_ROOT), 0, 0, 'title_setup'); -print '
'; -print $langs->trans("BackupDesc",DOL_DATA_ROOT); +print '
'; +print $langs->trans("BackupDesc", DOL_DATA_ROOT); print '
'; print '
'; @@ -128,7 +138,7 @@ print '
';
1 trans("BackupDesc3",$dolibarr_main_db_name).'
'; +print $langs->trans("BackupDesc3", $dolibarr_main_db_name).'
'; //print $langs->trans("BackupDescY").'
'; print '
'; ?> @@ -166,7 +176,7 @@ print '';
@@ -211,6 +221,7 @@ print '';
+
global->MYSQL_OLD_OPTION_DISABLE_FK)) { ?> @@ -233,14 +244,6 @@ print '';
- - -
@@ -453,8 +456,10 @@ print "\n";
-
" id="buttonGo" />
+
+ " id="buttonGo"> + +

'.$langs->trans("BackupResult").': '; print $_SESSION["commandbackupresult"]; @@ -476,7 +481,7 @@ if (! empty($_SESSION["commandbackuplastdone"])) } if (! empty($_SESSION["commandbackuptorun"])) { - print '
'.$langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user).':
'."\n"; + print '
'.$langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser", $dolibarr_main_db_user, $dolibarr_main_db_user).':
'."\n"; print '
'."\n"; print ajax_autoselect("commandbackuptoruntext", 0); print '
'; @@ -505,8 +510,8 @@ print '';
admin->dir_output.'/backup','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1); -$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'backup/',1,0,$langs->trans("NoBackupFileAvailable"),0,$langs->trans("PreviousDumpFiles")); +$filearray=dol_dir_list($conf->admin->dir_output.'/backup', 'files', 0, '', '', $sortfield, (strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC), 1); +$result=$formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'backup/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousDumpFiles")); print '
'; ?> @@ -526,7 +531,7 @@ print '
';
2 trans("BackupDesc2",DOL_DATA_ROOT).'
'; +print $langs->trans("BackupDesc2", DOL_DATA_ROOT).'
'; print $langs->trans("BackupDescX").'

'; ?> @@ -582,7 +587,7 @@ print "\n"; ?>
-
" id="buttonGo" />

@@ -593,8 +598,8 @@ print "\n";
admin->dir_output.'/documents','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1); -$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'documents/',1,0,$langs->trans("NoBackupFileAvailable"),0,$langs->trans("PreviousDumpFiles")); +$filearray=dol_dir_list($conf->admin->dir_output.'/documents', 'files', 0, '', '', $sortfield, (strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC), 1); +$result=$formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'documents/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousDumpFiles")); print '
'; ?> @@ -605,9 +610,6 @@ print '
';
- - - load("admin"); -$action=GETPOST('action','alpha'); -$what=GETPOST('what','alpha'); -$export_type=GETPOST('export_type','alpha'); -$file=GETPOST('zipfilename_template','alpha'); +$action=GETPOST('action', 'alpha'); +$what=GETPOST('what', 'alpha'); +$export_type=GETPOST('export_type', 'alpha'); +$file=GETPOST('zipfilename_template', 'alpha'); $compression = GETPOST('compression'); $file = dol_sanitizeFileName($file); -$sortfield = GETPOST('sortfield','alpha'); -$sortorder = GETPOST('sortorder','alpha'); -$page = GETPOST("page",'int'); +$sortfield = GETPOST('sortfield', 'alpha'); +$sortorder = GETPOST('sortorder', 'alpha'); +$page = GETPOST("page", 'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="date"; if ($page < 0) { $page = 0; } elseif (empty($page)) $page = 0; -$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; $offset = $limit * $page; if (! $user->admin) accessforbidden(); @@ -112,21 +112,27 @@ $utils = new Utils($db); if ($compression == 'zip') { - $ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression); + $ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression, '/(\.log|\/temp\/|documents\/admin\/documents\/)/'); if ($ret < 0) { - $errormsg = $langs->trans("ErrorFailedToWriteInDir",$outputfile); + $errormsg = $langs->trans("ErrorFailedToWriteInDir", $outputdir); } } elseif (in_array($compression, array('gz', 'bz'))) { - $file = substr($file, 0, strrpos($file, '.')); - $file .= '.tar'; - $cmd = 'tar -cf '.$outputdir."/".$file." --exclude=documents/admin/documents -C ".DOL_DATA_ROOT." ".DOL_DATA_ROOT."/../documents/"; - exec($cmd, $out, $retval); - //var_dump($cmd, DOL_DATA_ROOT);exit; + $userlogin = ($user->login ? $user->login : 'unknown'); - if ($retval != 0) + $outputfile = $conf->admin->dir_temp.'/export_files.'.$userlogin.'.out'; // File used with popen method + + $file = substr($file, 0, strrpos($file, '.')); + $file .= '.tar'; + // We also exclude '/temp/' dir and 'documents/admin/documents' + $cmd = "tar -cf ".$outputdir."/".$file." --exclude-vcs --exclude 'temp' --exclude 'dolibarr.log' --exclude='documents/admin/documents' -C ".dirname(DOL_DATA_ROOT)." ".basename(DOL_DATA_ROOT); + + $result = $utils->executeCLI($cmd, $outputfile); + + $retval = $result['error']; + if ($result['result'] || ! empty($retval)) { $langs->load("errors"); dol_syslog("Documents tar retval after exec=".$retval, LOG_ERR); @@ -136,15 +142,17 @@ elseif (in_array($compression, array('gz', 'bz'))) { if ($compression == 'gz') { - $cmd = "gzip " . $outputdir."/".$file; + $cmd = "gzip -f " . $outputdir."/".$file; } if ($compression == 'bz') { - $cmd = "bzip2 " . $outputdir."/".$file; + $cmd = "bzip2 -f " . $outputdir."/".$file; } - exec($cmd, $out, $retval); - if ($retval != 0) + $result = $utils->executeCLI($cmd, $outputfile); + + $retval = $result['error']; + if ($result['result'] || ! empty($retval)) { $errormsg = 'Error '.$compression.' generation return '.$retval; unlink($outputdir."/".$file); @@ -166,4 +174,3 @@ header("Location: dolibarr_export.php"); $time_end = time(); $db->close(); - diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 5007e642300..86eff6613c1 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -32,15 +32,15 @@ class Utils */ public $db; - var $output; // Used by Cron method to return message - var $result; // Used by Cron method to return data + public $output; // Used by Cron method to return message + public $result; // Used by Cron method to return data /** * Constructor * * @param DoliDB $db Database handler */ - function __construct($db) + public function __construct($db) { $this->db = $db; } @@ -54,7 +54,7 @@ class Utils * @param int $nbsecondsold Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold' * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ - function purgeFiles($choice = 'tempfilesold', $nbsecondsold = 86400) + public function purgeFiles($choice = 'tempfilesold', $nbsecondsold = 86400) { global $conf, $langs, $dolibarr_main_data_root; @@ -106,7 +106,7 @@ class Utils if (! empty($conf->syslog->enabled)) { $filelog=$conf->global->SYSLOG_FILE; - $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); + $filelog=preg_replace('/DOL_DATA_ROOT/i', DOL_DATA_ROOT, $filelog); $alreadyincluded=false; foreach ($filesarray as $tmpcursor) @@ -193,7 +193,7 @@ class Utils * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ - function dumpDatabase($compression='none', $type='auto', $usedefault=1, $file='auto', $keeplastnfiles=0, $execmethod=0) + public function dumpDatabase($compression = 'none', $type = 'auto', $usedefault = 1, $file = 'auto', $keeplastnfiles = 0, $execmethod = 0) { global $db, $conf, $langs, $dolibarr_main_data_root; global $dolibarr_main_db_name, $dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_port, $dolibarr_main_db_pass; @@ -251,8 +251,8 @@ class Utils // Parameteres execution $command = $cmddump; - $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters + $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. + if (preg_match("/\s/", $command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host; @@ -262,7 +262,6 @@ class Utils if (GETPOST("disable_fk", "alpha") || $usedefault) $param.=" -K"; if (GETPOST("sql_compat", "alpha") && GETPOST("sql_compat", "alpha") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat", "alpha")); if (GETPOST("drop_database", "alpha")) $param.=" --add-drop-database"; - if (GETPOST("use_mysql_quick_param", "alpha"))$param.=" --quick"; if (GETPOST("sql_structure", "alpha") || $usedefault) { if (GETPOST("drop", "alpha") || $usedefault) $param.=" --add-drop-table=TRUE"; @@ -292,8 +291,8 @@ class Utils $paramclear=$param; if (! empty($dolibarr_main_db_pass)) { - $paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"'; - $paramclear.=' -p"'.str_replace(array('"','`'),array('\"','\`'),$dolibarr_main_db_pass).'"'; + $paramcrypted.=' -p"'.preg_replace('/./i', '*', $dolibarr_main_db_pass).'"'; + $paramclear.=' -p"'.str_replace(array('"','`'), array('\"','\`'), $dolibarr_main_db_pass).'"'; } $errormsg=''; @@ -317,27 +316,29 @@ class Utils // TODO Replace with executeCLI function if ($execmethod == 1) { - exec($fullcommandclear, $readt, $retval); - $result = $retval; + $output_arr = array(); $retval = null; + exec($fullcommandclear, $output_arr, $retval); if ($retval != 0) { $langs->load("errors"); dol_syslog("Datadump retval after exec=".$retval, LOG_ERR); - $error = 'Error '.$retval; + $errormsg = 'Error '.$retval; $ok=0; } else { $i=0; - if (!empty($readt)) - foreach($readt as $key=>$read) + if (!empty($output_arr)) { - $i++; // output line number - if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; - fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); - if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; - elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; + foreach($output_arr as $key => $read) + { + $i++; // output line number + if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; + fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); + if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) $ok=1; + elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) $ok=1; + } } } } @@ -351,9 +352,9 @@ class Utils $read = fgets($handlein); // Exclude warning line we don't want if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; - fwrite($handle,$read); - if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; - elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; + fwrite($handle, $read); + if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) $ok=1; + elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) $ok=1; } pclose($handlein); } @@ -369,7 +370,7 @@ class Utils else { $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); $errormsg=$langs->trans("ErrorFailedToWriteInDir"); } @@ -380,18 +381,18 @@ class Utils if ($handle) { // Get 2048 first chars of error message. - $errormsg = fgets($handle,2048); + $errormsg = fgets($handle, 2048); // Close file if ($compression == 'none') fclose($handle); if ($compression == 'gz') gzclose($handle); if ($compression == 'bz') bzclose($handle); - if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur + if ($ok && preg_match('/^-- MySql/i', $errormsg)) $errormsg=''; // Pas erreur else { // Renommer fichier sortie en fichier erreur //print "$outputfile -> $outputerror"; @dol_delete_file($outputerror, 1, 0, 0, null, false, 0); - @rename($outputfile,$outputerror); + @rename($outputfile, $outputerror); // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide if (! $errormsg) { @@ -450,8 +451,8 @@ class Utils // Parameteres execution $command = $cmddump; - $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters + $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. + if (preg_match("/\s/", $command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); //$param="-F c"; @@ -515,7 +516,7 @@ class Utils * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method * @return array array('result'=>...,'output'=>...,'error'=>...). result = 0 means OK. */ - function executeCLI($command, $outputfile, $execmethod=0) + public function executeCLI($command, $outputfile, $execmethod = 0) { global $conf, $langs; @@ -535,6 +536,7 @@ class Utils if ($execmethod == 1) { + $retval = null; exec($command, $output_arr, $retval); $result = $retval; if ($retval != 0) @@ -546,7 +548,6 @@ class Utils } if ($execmethod == 2) // With this method, there is no way to get the return code, only output { - $ok=0; $handle = fopen($outputfile, 'w+b'); if ($handle) { @@ -555,7 +556,7 @@ class Utils while (!feof($handlein)) { $read = fgets($handlein); - fwrite($handle,$read); + fwrite($handle, $read); $output_arr[]=$read; } pclose($handlein); @@ -584,14 +585,15 @@ class Utils * @param string $module Module name * @return int <0 if KO, >0 if OK */ - function generateDoc($module) + public function generateDoc($module) { - global $conf, $langs; + global $conf, $langs, $user, $mysoc; global $dirins; $error = 0; $modulelowercase=strtolower($module); + $now=dol_now(); // Dir for module $dir = $dirins.'/'.$modulelowercase; @@ -621,11 +623,12 @@ class Utils exit; } - $arrayversion=explode('.',$moduleobj->version,3); + $arrayversion=explode('.', $moduleobj->version, 3); if (count($arrayversion)) { $FILENAMEASCII=strtolower($module).'.asciidoc'; - $FILENAMEDOC=strtolower($module).'.html'; // TODO Use/text PDF + $FILENAMEDOC=strtolower($module).'.html'; + $FILENAMEDOCPDF=strtolower($module).'.pdf'; $dirofmodule = dol_buildpath(strtolower($module), 0); $dirofmoduledoc = dol_buildpath(strtolower($module), 0).'/doc'; @@ -641,13 +644,25 @@ class Utils return -1; } - $conf->global->MODULEBUILDER_ASCIIDOCTOR='asciidoctor'; - if (empty($conf->global->MODULEBUILDER_ASCIIDOCTOR)) + if (empty($conf->global->MODULEBUILDER_ASCIIDOCTOR) && empty($conf->global->MODULEBUILDER_ASCIIDOCTORPDF)) { $this->error = 'Setup of module ModuleBuilder not complete'; return -1; } + // Copy some files into temp directory, so instruction include::ChangeLog.md[] will works inside the asciidoc file. + dol_copy($dirofmodule.'/README.md', $dirofmoduletmp.'/README.md', 0, 1); + dol_copy($dirofmodule.'/ChangeLog.md', $dirofmoduletmp.'/ChangeLog.md', 0, 1); + + // Replace into README.md and ChangeLog.md (in case they are included into documentation with tag __README__ or __CHANGELOG__) + $arrayreplacement=array(); + $arrayreplacement['/^#\s.*/m']=''; // Remove first level of title into .md files + $arrayreplacement['/^#/m']='##'; // Add on # to increase level + + dolReplaceInFile($dirofmoduletmp.'/README.md', $arrayreplacement, '', 0, 0, 1); + dolReplaceInFile($dirofmoduletmp.'/ChangeLog.md', $arrayreplacement, '', 0, 0, 1); + + $destfile=$dirofmoduletmp.'/'.$FILENAMEASCII; $fhandle = fopen($destfile, 'w+'); @@ -680,35 +695,48 @@ class Utils $i++; } - fwrite($fhandle, "\n\n\n== DATA SPECIFICATIONS...\n\n"); - - // TODO - fwrite($fhandle, "TODO..."); - - - fwrite($fhandle, "\n\n\n== CHANGELOG...\n\n"); - - // TODO - fwrite($fhandle, "TODO..."); - - - fclose($fhandle); - } - // Copy some files into temp directory - dol_copy($dirofmodule.'/README.md', $dirofmoduletmp.'/README.md', 0, 1); - dol_copy($dirofmodule.'/ChangeLog.md', $dirofmoduletmp.'/ChangeLog.md', 0, 1); + $contentreadme=file_get_contents($dirofmoduletmp.'/README.md'); + $contentchangelog=file_get_contents($dirofmoduletmp.'/ChangeLog.md'); + + include DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + + //var_dump($phpfileval['fullname']); + $arrayreplacement=array( + 'mymodule'=>strtolower($module), + 'MyModule'=>$module, + 'MYMODULE'=>strtoupper($module), + 'My module'=>$module, + 'my module'=>$module, + 'Mon module'=>$module, + 'mon module'=>$module, + 'htdocs/modulebuilder/template'=>strtolower($module), + '__MYCOMPANY_NAME__'=>$mysoc->name, + '__KEYWORDS__'=>$module, + '__USER_FULLNAME__'=>$user->getFullName($langs), + '__USER_EMAIL__'=>$user->email, + '__YYYY-MM-DD__'=>dol_print_date($now, 'dayrfc'), + '---Put here your own copyright and developer email---'=>dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':''), + '__DATA_SPECIFICATION__'=>'Not yet available', + '__README__'=>dolMd2Asciidoc($contentreadme), + '__CHANGELOG__'=>dolMd2Asciidoc($contentchangelog), + ); + + dolReplaceInFile($destfile, $arrayreplacement); + } // Launch doc generation $currentdir = getcwd(); chdir($dirofmodule); + require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php'; + $utils = new Utils($db); + + // Build HTML doc $command=$conf->global->MODULEBUILDER_ASCIIDOCTOR.' '.$destfile.' -n -o '.$dirofmoduledoc.'/'.$FILENAMEDOC; $outfile=$dirofmoduletmp.'/out.tmp'; - require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php'; - $utils = new Utils($this->db); $resarray = $utils->executeCLI($command, $outfile); if ($resarray['result'] != '0') { @@ -716,6 +744,16 @@ class Utils } $result = ($resarray['result'] == 0) ? 1 : 0; + // Build PDF doc + $command=$conf->global->MODULEBUILDER_ASCIIDOCTORPDF.' '.$destfile.' -n -o '.$dirofmoduledoc.'/'.$FILENAMEDOCPDF; + $outfile=$dirofmoduletmp.'/outpdf.tmp'; + $resarray = $utils->executeCLI($command, $outfile); + if ($resarray['result'] != '0') + { + $this->error = $resarray['error'].' '.$resarray['output']; + } + $result = ($resarray['result'] == 0) ? 1 : 0; + chdir($currentdir); } else @@ -751,7 +789,7 @@ class Utils * * @return int 0 if OK, < 0 if KO */ - function compressSyslogs() + public function compressSyslogs() { global $conf; @@ -857,7 +895,7 @@ class Utils $this->output = 'Archive log files (keeping last SYSLOG_FILE_SAVES='.$nbSaves.' files) done.'; return 0; - } + } /** Backup the db OR just a table without mysqldump binary, with PHP only (does not require any exec permission) * Author: David Walsh (http://davidwalsh.name/backup-mysql-database-php) @@ -869,7 +907,7 @@ class Utils * @param string $tables Table name or '*' for all * @return int <0 if KO, >0 if OK */ - function backupTables($outputfile, $tables='*') + public function backupTables($outputfile, $tables = '*') { global $db, $langs; global $errormsg; @@ -896,7 +934,7 @@ class Utils } else { - $tables = is_array($tables) ? $tables : explode(',',$tables); + $tables = is_array($tables) ? $tables : explode(',', $tables); } //cycle through @@ -904,7 +942,7 @@ class Utils if (fwrite($handle, '') === false) { $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); $errormsg=$langs->trans("ErrorFailedToWriteInDir"); return -1; } @@ -947,9 +985,9 @@ class Utils // Saving the table structure fwrite($handle, "\n--\n-- Table structure for table `".$table."`\n--\n"); - if (GETPOST("nobin_drop")) fwrite($handle,"DROP TABLE IF EXISTS `".$table."`;\n"); // Dropping table if exists prior to re create it - fwrite($handle,"/*!40101 SET @saved_cs_client = @@character_set_client */;\n"); - fwrite($handle,"/*!40101 SET character_set_client = utf8 */;\n"); + if (GETPOST("nobin_drop")) fwrite($handle, "DROP TABLE IF EXISTS `".$table."`;\n"); // Dropping table if exists prior to re create it + fwrite($handle, "/*!40101 SET @saved_cs_client = @@character_set_client */;\n"); + fwrite($handle, "/*!40101 SET character_set_client = utf8 */;\n"); $resqldrop=$db->query('SHOW CREATE TABLE '.$table); $row2 = $db->fetch_row($resqldrop); if (empty($row2[1])) @@ -958,7 +996,7 @@ class Utils } else { - fwrite($handle,$row2[1].";\n"); + fwrite($handle, $row2[1].";\n"); //fwrite($handle,"/*!40101 SET character_set_client = @saved_cs_client */;\n\n"); // Dumping the data (locking the table and disabling the keys check while doing the process) @@ -972,7 +1010,7 @@ class Utils while($row = $db->fetch_row($result)) { // For each row of data we print a line of INSERT - fwrite($handle,'INSERT '.$delayed.$ignore.'INTO `'.$table.'` VALUES ('); + fwrite($handle, 'INSERT '.$delayed.$ignore.'INTO `'.$table.'` VALUES ('); $columns = count($row); for($j=0; $j<$columns; $j++) { // Processing each columns of the row to ensure that we correctly save the value (eg: add quotes for string - in fact we add quotes for everything, it's easier) @@ -991,11 +1029,11 @@ class Utils $row[$j] = "'".$row[$j]."'"; } } - fwrite($handle,implode(',', $row).");\n"); + fwrite($handle, implode(',', $row).");\n"); } if (GETPOST("nobin_disable_fk")) fwrite($handle, "ALTER TABLE `".$table."` ENABLE KEYS;\n"); // Enabling back the keys/index checking if (!GETPOST("nobin_nolocks")) fwrite($handle, "UNLOCK TABLES;\n"); // Unlocking the table - fwrite($handle,"\n\n\n"); + fwrite($handle, "\n\n\n"); } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 295bda85d53..d2aee3e6a30 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -4,6 +4,7 @@ * Copyright (C) 2012-2016 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2019 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +35,7 @@ */ function dol_basename($pathfile) { - return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/')); + return preg_replace('/^.*\/([^\/]+)$/', '$1', rtrim($pathfile, '/')); } /** @@ -54,9 +55,9 @@ function dol_basename($pathfile) * @param string $relativename For recursive purpose only. Must be "" at first call. * @param string $donotfollowsymlinks Do not follow symbolic links * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file',...) - * @see dol_dir_list_indatabase + * @see dol_dir_list_in_database() */ -function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0) +function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0, $nohook = 0, $relativename = "", $donotfollowsymlinks = 0) { global $db, $hookmanager; global $object; @@ -68,7 +69,7 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil $loadsize=($mode==1||$mode==3)?true:false; // Clean parameters - $path=preg_replace('/([\\/]+)$/i','',$path); + $path=preg_replace('/([\\/]+)$/i', '', $path); $newpath=dol_osencode($path); $reshook = 0; @@ -116,9 +117,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil $excludefilterarray=array('^\.'); if (is_array($excludefilter)) { - $excludefilterarray=array_merge($excludefilterarray,$excludefilter); + $excludefilterarray=array_merge($excludefilterarray, $excludefilter); } - else if ($excludefilter) $excludefilterarray[]=$excludefilter; + elseif ($excludefilter) $excludefilterarray[]=$excludefilter; // Check if file is qualified foreach($excludefilterarray as $filt) { @@ -140,9 +141,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file); if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file); - if (! $filter || preg_match('/'.$filter.'/i',$file)) // We do not search key $filter into all $path, only into $file part + if (! $filter || preg_match('/'.$filter.'/i', $file)) // We do not search key $filter into all $path, only into $file part { - preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg); + preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( "name" => $file, @@ -167,15 +168,15 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil } } } - else if (! $isdir && (($types == "files") || ($types == "all"))) + elseif (! $isdir && (($types == "files") || ($types == "all"))) { // Add file into file_list array if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file); if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file); - if (! $filter || preg_match('/'.$filter.'/i',$file)) // We do not search key $filter into $path, only into $file + if (! $filter || preg_match('/'.$filter.'/i', $file)) // We do not search key $filter into $path, only into $file { - preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg); + preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( "name" => $file, @@ -194,15 +195,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil closedir($dir); // Obtain a list of columns - if (! empty($sortcriteria)) + if (! empty($sortcriteria) && $sortorder) { - $myarray=array(); - foreach ($file_list as $key => $row) - { - $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:''); - } - // Sort the data - if ($sortorder) array_multisort($myarray, $sortorder, $file_list); + $file_list = dol_sort_array($file_list, $sortcriteria, ($sortorder == SORT_ASC ? 'asc' : 'desc')); } } } @@ -224,9 +219,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil * @param string $sortorder Sort order (SORT_ASC, SORT_DESC) * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like description * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','type'=>'dir|file',...) - * @see dol_dir_list + * @see dol_dir_list() */ -function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0) +function dol_dir_list_in_database($path, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0) { global $conf, $db; @@ -248,7 +243,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc $obj = $db->fetch_object($resql); if ($obj) { - preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); + preg_match('/([^\/]+)\/[^\/]+$/', DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename, $reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( "rowid" => $obj->rowid, @@ -313,11 +308,11 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir) global $object; if (! empty($object->id)) { - if (! empty($conf->product->enabled)) $upload_dirold = $conf->product->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2),1,1).'/'.substr(substr("000".$object->id, -2),0,1).'/'.$object->id."/photos"; - else $upload_dirold = $conf->service->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2),1,1).'/'.substr(substr("000".$object->id, -2),0,1).'/'.$object->id."/photos"; + if (! empty($conf->product->enabled)) $upload_dirold = $conf->product->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2), 1, 1).'/'.substr(substr("000".$object->id, -2), 0, 1).'/'.$object->id."/photos"; + else $upload_dirold = $conf->service->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2), 1, 1).'/'.substr(substr("000".$object->id, -2), 0, 1).'/'.$object->id."/photos"; - $relativedirold = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dirold); - $relativedirold = preg_replace('/^[\\/]/','',$relativedirold); + $relativedirold = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $upload_dirold); + $relativedirold = preg_replace('/^[\\/]/', '', $relativedirold); $filearrayindatabase = array_merge($filearrayindatabase, dol_dir_list_in_database($relativedirold, '', null, 'name', SORT_ASC)); } @@ -353,7 +348,7 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir) $filearray[$key]['cover']=0; $filearray[$key]['acl']=''; - $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filearray[$key]['fullname']); + $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filearray[$key]['fullname']); if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file { dol_syslog("list_of_documents We found a file called '".$filearray[$key]['name']."' not indexed into database. We add it"); @@ -442,6 +437,18 @@ function dol_is_dir($folder) else return false; } +/** + * Return if path is empty + * + * @param string $dir Path of Directory + * @return boolean True or false + */ +function dol_is_dir_empty($dir) +{ + if (!is_readable($dir)) return false; + return (count(scandir($dir)) == 2); +} + /** * Return if path is a file * @@ -477,7 +484,7 @@ function dol_is_url($url) $tmpprot=array('file','http','https','ftp','zlib','data','ssh','ssh2','ogg','expect'); foreach($tmpprot as $prot) { - if (preg_match('/^'.$prot.':/i',$url)) return true; + if (preg_match('/^'.$prot.':/i', $url)) return true; } return false; } @@ -515,7 +522,7 @@ function dol_dir_is_emtpy($folder) * * @param string $file Filename * @return int <0 if KO, Number of lines in files if OK - * @see dol_nboflines + * @see dol_nboflines() */ function dol_count_nb_of_line($file) { @@ -523,7 +530,7 @@ function dol_count_nb_of_line($file) $newfile=dol_osencode($file); //print 'x'.$file; - $fp=fopen($newfile,'r'); + $fp=fopen($newfile, 'r'); if ($fp) { while (!feof($fp)) @@ -570,19 +577,20 @@ function dol_filemtime($pathoffile) /** * Make replacement of strings into a file. * - * @param string $srcfile Source file (can't be a directory) - * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) - * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. - * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' - * @param int $indexdatabase 1=index new file into database. - * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dol_copy dolReplaceRegExInFile + * @param string $srcfile Source file (can't be a directory) + * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) + * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. + * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' + * @param int $indexdatabase 1=index new file into database. + * @param int $arrayreplacementisregex 1=Array of replacement is regex + * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK + * @see dol_copy() */ -function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) +function dolReplaceInFile($srcfile, $arrayreplacement, $destfile = '', $newmask = 0, $indexdatabase = 0, $arrayreplacementisregex = 0) { global $conf; - dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase); + dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase." arrayreplacementisregex=".$arrayreplacementisregex); if (empty($srcfile)) return -1; if (empty($destfile)) $destfile=$srcfile; @@ -613,7 +621,17 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, // Create $newpathoftmpdestfile from $newpathofsrcfile $content = file_get_contents($newpathofsrcfile, 'r'); - $content = make_substitutions($content, $arrayreplacement, null); + if (empty($arrayreplacementisregex)) + { + $content = make_substitutions($content, $arrayreplacement, null); + } + else + { + foreach ($arrayreplacement as $key => $value) + { + $content = preg_replace($key, $value, $content); + } + } file_put_contents($newpathoftmpdestfile, $content); @chmod($newpathoftmpdestfile, octdec($newmask)); @@ -637,21 +655,6 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, return 1; } -/** - * Make replacement of strings into a file. - * - * @param string $srcfile Source file (can't be a directory) - * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) - * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. - * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' - * @param int $indexdatabase Index new file into database. - * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dol_copy dolReplaceInFile - */ -function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) -{ - // TODO -} /** * Copy a file to another file. @@ -661,9 +664,9 @@ function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newma * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' * @param int $overwriteifexists Overwrite file if exists (1 by default) * @return int <0 if error, 0 if nothing done (dest file already exists and overwriteifexists=0), >0 if OK - * @see dol_delete_file + * @see dol_delete_file() dolCopyDir() */ -function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1) +function dol_copy($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1) { global $conf; @@ -717,9 +720,9 @@ function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1) * @param int $overwriteifexists Overwrite file if exists (1 by default) * @param array $arrayreplacement Array to use to replace filenames with another one during the copy (works only on file names, not on directory names). * @return int <0 if error, 0 if nothing done (all files already exists and overwriteifexists=0), >0 if OK - * @see dol_copy + * @see dol_copy() */ -function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null) +function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement = null) { global $conf; @@ -809,9 +812,9 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep * @param int $testvirus Do an antivirus test. Move is canceled if a virus is found. * @param int $indexdatabase Index new file into database. * @return boolean True if OK, false if KO - * @see dol_move_uploaded_file + * @see dol_move_uploaded_file() */ -function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1) +function dol_move($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1, $testvirus = 0, $indexdatabase = 1) { global $user, $db, $conf; $result=false; @@ -860,8 +863,8 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi if ($result && $indexdatabase) { // Rename entry into ecm database - $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile); - $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile); + $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $srcfile); + $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $destfile); if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file { $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore); @@ -956,18 +959,18 @@ function dol_unescapefile($filename) */ function dolCheckVirus($src_file) { - global $conf, $db; + global $conf; if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) { if (! class_exists('AntiVir')) { require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php'; } - $antivir = new AntiVir($db); + $antivir=new AntiVir($db); $result = $antivir->dol_avscan_file($src_file); if ($result < 0) // If virus or error, we stop here { - $reterrors = $antivir->errors; + $reterrors=$antivir->errors; return $reterrors; } } @@ -982,6 +985,7 @@ function dolCheckVirus($src_file) * - This function can be used only into a HTML page context. Use dol_move if you are outside. * - Test on antivirus is always done (if antivirus set). * - Database of files is NOT updated (this is done by dol_add_file_process() that calls this function). + * - Extension .noexe may be added if file is executable and MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED is not set. * * @param string $src_file Source full path filename ($_FILES['field']['tmp_name']) * @param string $dest_file Target full path filename ($_FILES['field']['name']) @@ -990,10 +994,10 @@ function dolCheckVirus($src_file) * @param integer $uploaderrorcode Value of PHP upload error code ($_FILES['field']['error']) * @param int $nohook Disable all hooks * @param string $varfiles _FILES var name - * @return int|string >0 if OK, <0 or string if KO - * @see dol_move + * @return int >0 if OK, <0 or string if KO + * @see dol_move() */ -function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile') +function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan = 0, $uploaderrorcode = 0, $nohook = 0, $varfiles = 'addedfile') { global $conf, $db, $user, $langs; global $object, $hookmanager; @@ -1045,8 +1049,8 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable $checkvirusarray=dolCheckVirus($src_file); if (count($checkvirusarray)) { - 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); - return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray); + dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.join(',', $checkvirusarray), LOG_WARNING); + return 'ErrorFileIsInfectedWithAVirus: '.join(',', $checkvirusarray); } } @@ -1060,15 +1064,15 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable // Security: // We refuse cache files/dirs, upload using .. and pipes into filenames. - if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file)) + if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) { dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); return -1; } // Security: - // On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers. - if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file)) + // We refuse cache files/dirs, upload using .. and pipes into filenames. + if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) { dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING); return -2; @@ -1134,9 +1138,9 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable * @param boolean $allowdotdot Allow to delete file path with .. inside. Never use this, it is reserved for migration purpose. * @param int $indexdatabase Try to remove also index entries. * @return boolean True if no error (file is deleted or if glob is used and there's nothing to delete), False if error - * @see dol_delete_dir + * @see dol_delete_dir() */ -function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1) +function dol_delete_file($file, $disableglob = 0, $nophperrors = 0, $nohook = 0, $object = null, $allowdotdot = false, $indexdatabase = 1) { global $db, $conf, $user, $langs; global $hookmanager; @@ -1148,7 +1152,7 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje // Security: // We refuse transversal using .. and pipes into filenames. - if ((! $allowdotdot && preg_match('/\.\./',$file)) || preg_match('/[<>|]/',$file)) + if ((! $allowdotdot && preg_match('/\.\./', $file)) || preg_match('/[<>|]/', $file)) { dol_syslog("Refused to delete file ".$file, LOG_WARNING); return false; @@ -1181,8 +1185,8 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje if (empty($disableglob) && ! empty($file_osencoded)) { $ok=true; - $globencoded=str_replace('[','\[',$file_osencoded); - $globencoded=str_replace(']','\]',$globencoded); + $globencoded=str_replace('[', '\[', $file_osencoded); + $globencoded=str_replace(']', '\]', $globencoded); $listofdir=glob($globencoded); if (! empty($listofdir) && is_array($listofdir)) { @@ -1195,7 +1199,7 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje dol_syslog("Removed file ".$filename, LOG_DEBUG); // Delete entry into ecm database - $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); + $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filename); if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file { $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); @@ -1217,9 +1221,12 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje } } } - else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); - // TODO Failure to remove can be because file was already removed or because of permission - // If error because it does not exists, we should return true, and we should return false if this is a permission problem + else + { + dol_syslog("Failed to remove file ".$filename, LOG_WARNING); + // TODO Failure to remove can be because file was already removed or because of permission + // If error because it does not exists, we should return true, and we should return false if this is a permission problem + } } } else dol_syslog("No files to delete found", LOG_DEBUG); @@ -1244,13 +1251,13 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje * @param string $dir Directory to delete * @param int $nophperrors Disable all PHP output errors * @return boolean True if success, false if error - * @see dol_delete_file dol_copy + * @see dol_delete_file() dolCopyDir() */ -function dol_delete_dir($dir,$nophperrors=0) +function dol_delete_dir($dir, $nophperrors = 0) { // Security: // We refuse transversal using .. and pipes into filenames. - if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir)) + if (preg_match('/\.\./', $dir) || preg_match('/[<>|]/', $dir)) { dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); return false; @@ -1270,9 +1277,9 @@ function dol_delete_dir($dir,$nophperrors=0) * @param int $countdeleted Counter to count nb of elements found really deleted * @return int Number of files and directory we try to remove. NB really removed is returned into var by reference $countdeleted. */ -function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0) +function dol_delete_dir_recursive($dir, $count = 0, $nophperrors = 0, $onlysub = 0, &$countdeleted = 0) { - dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir,LOG_DEBUG); + dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir, LOG_DEBUG); if (dol_is_dir($dir)) { $dir_osencoded=dol_osencode($dir); @@ -1319,7 +1326,7 @@ function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$ * * @param object $object Object to clean * @return int 0 if error, 1 if OK - * @see dol_convert_file + * @see dol_convert_file() */ function dol_delete_preview($object) { @@ -1347,26 +1354,26 @@ function dol_delete_preview($object) // For new preview files if (file_exists($filepreviewnew) && is_writable($filepreviewnew)) { - if (! dol_delete_file($filepreviewnew,1)) + if (! dol_delete_file($filepreviewnew, 1)) { - $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewnew); + $object->error=$langs->trans("ErrorFailedToDeleteFile", $filepreviewnew); return 0; } } if (file_exists($filepreviewnewbis) && is_writable($filepreviewnewbis)) { - if (! dol_delete_file($filepreviewnewbis,1)) + if (! dol_delete_file($filepreviewnewbis, 1)) { - $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewnewbis); + $object->error=$langs->trans("ErrorFailedToDeleteFile", $filepreviewnewbis); return 0; } } // For old preview files if (file_exists($filepreviewold) && is_writable($filepreviewold)) { - if (! dol_delete_file($filepreviewold,1)) + if (! dol_delete_file($filepreviewold, 1)) { - $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewold); + $object->error=$langs->trans("ErrorFailedToDeleteFile", $filepreviewold); return 0; } } @@ -1379,9 +1386,9 @@ function dol_delete_preview($object) if (file_exists($preview) && is_writable($preview)) { - if ( ! dol_delete_file($preview,1) ) + if ( ! dol_delete_file($preview, 1) ) { - $object->error=$langs->trans("ErrorFailedToOpenFile",$preview); + $object->error=$langs->trans("ErrorFailedToOpenFile", $preview); return 0; } } @@ -1435,7 +1442,7 @@ function dol_meta_create($object) $nblignes = count($object->lines); $client = $object->thirdparty->name . " " . $object->thirdparty->address . " " . $object->thirdparty->zip . " " . $object->thirdparty->town; $meta = "REFERENCE=\"" . $object->ref . "\" - DATE=\"" . dol_print_date($object->date,'') . "\" + DATE=\"" . dol_print_date($object->date, '') . "\" NB_ITEMS=\"" . $nblignes . "\" CLIENT=\"" . $client . "\" AMOUNT_EXCL_TAX=\"" . $object->total_ht . "\" @@ -1447,13 +1454,13 @@ function dol_meta_create($object) $meta .= "ITEM_" . $i . "_QUANTITY=\"" . $object->lines[$i]->qty . "\" ITEM_" . $i . "_AMOUNT_WO_TAX=\"" . $object->lines[$i]->total_ht . "\" ITEM_" . $i . "_VAT=\"" .$object->lines[$i]->tva_tx . "\" - ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n","",nl2br($object->lines[$i]->desc)) . "\" + ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n", "", nl2br($object->lines[$i]->desc)) . "\" "; } } - $fp = fopen($file,"w"); - fputs($fp,$meta); + $fp = fopen($file, "w"); + fputs($fp, $meta); fclose($fp); if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); @@ -1478,7 +1485,7 @@ function dol_meta_create($object) * @param string $trackid Track id (used to prefix name of session vars to avoid conflict) * @return void */ -function dol_init_file_process($pathtoscan='', $trackid='') +function dol_init_file_process($pathtoscan = '', $trackid = '') { $listofpaths=array(); $listofnames=array(); @@ -1486,7 +1493,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') if ($pathtoscan) { - $listoffiles=dol_dir_list($pathtoscan,'files'); + $listoffiles=dol_dir_list($pathtoscan, 'files'); foreach($listoffiles as $key => $val) { $listofpaths[]=$val['fullname']; @@ -1495,9 +1502,9 @@ function dol_init_file_process($pathtoscan='', $trackid='') } } $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; - $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths); - $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames); - $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes); + $_SESSION["listofpaths".$keytoavoidconflict]=join(';', $listofpaths); + $_SESSION["listofnames".$keytoavoidconflict]=join(';', $listofnames); + $_SESSION["listofmimes".$keytoavoidconflict]=join(';', $listofmimes); } @@ -1516,7 +1523,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') * @param int $generatethumbs 1=Generate also thumbs for uploaded image files * @return int <=0 if KO, >0 if OK */ -function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1) +function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesession = 0, $varfiles = 'addedfile', $savingdocmask = '', $link = null, $trackid = '', $generatethumbs = 1) { global $db,$user,$conf,$langs; @@ -1546,8 +1553,8 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio if ($savingdocmask) { - $destfull=$upload_dir . "/" . preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask); - $destfile=preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask); + $destfull=$upload_dir . "/" . preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); + $destfile=preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); } // dol_sanitizeFileName the file name and lowercase extension @@ -1614,7 +1621,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio { setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors'); } - else if (preg_match('/ErrorFileIsInfectedWithAVirus/',$resupload)) // Files infected by a virus + elseif (preg_match('/ErrorFileIsInfectedWithAVirus/', $resupload)) // Files infected by a virus { setEventMessages($langs->trans("ErrorFileIsInfectedWithAVirus"), null, 'errors'); } @@ -1666,7 +1673,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio * @param string $trackid Track id (used to prefix name of session vars to avoid conflict) * @return void */ -function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile=1,$trackid='') +function dol_remove_file_process($filenb, $donotupdatesession = 0, $donotdeletefile = 1, $trackid = '') { global $db,$user,$conf,$langs,$_FILES; @@ -1677,22 +1684,22 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= $listofnames=array(); $listofmimes=array(); $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; - if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]); - if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]); - if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]); + if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';', $_SESSION["listofpaths".$keytoavoidconflict]); + if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';', $_SESSION["listofnames".$keytoavoidconflict]); + if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';', $_SESSION["listofmimes".$keytoavoidconflict]); if ($keytodelete >= 0) { $pathtodelete=$listofpaths[$keytodelete]; $filetodelete=$listofnames[$keytodelete]; - if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete,1); // The delete of ecm database is inside the function dol_delete_file + if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete, 1); // The delete of ecm database is inside the function dol_delete_file else $result=0; if ($result >= 0) { if (empty($donotdeletefile)) { $langs->load("other"); - setEventMessages($langs->trans("FileWasRemoved",$filetodelete), null, 'mesgs'); + setEventMessages($langs->trans("FileWasRemoved", $filetodelete), null, 'mesgs'); } if (empty($donotupdatesession)) { @@ -1718,13 +1725,13 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= * @param int $setsharekey Set also the share key * @return int <0 if KO, 0 if nothing done, >0 if OK */ -function addFileIntoDatabaseIndex($dir, $file, $fullpathorig='', $mode='uploaded', $setsharekey=0) +function addFileIntoDatabaseIndex($dir, $file, $fullpathorig = '', $mode = 'uploaded', $setsharekey = 0) { global $db, $user; $result = 0; - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $dir); + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $dir); if (! preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir { @@ -1766,7 +1773,7 @@ function addFileIntoDatabaseIndex($dir, $file, $fullpathorig='', $mode='uploaded * @param string $mode How file was created ('uploaded', 'generated', ...) * @return int <0 if KO, 0 if nothing done, >0 if OK */ -function deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded') +function deleteFilesIntoDatabaseIndex($dir, $file, $mode = 'uploaded') { global $conf, $db, $user; @@ -1780,7 +1787,7 @@ function deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded') $db->begin(); - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $dir); + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $dir); $filename = basename($file); $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); @@ -1820,38 +1827,36 @@ function deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded') * @param string $fileinput Input file name * @param string $ext Format of target file (It is also extension added to file if fileoutput is not provided). * @param string $fileoutput Output filename + * @param string $page Page number if we convert a PDF into png * @return int <0 if KO, 0=Nothing done, >0 if OK */ -function dol_convert_file($fileinput, $ext='png', $fileoutput='') +function dol_convert_file($fileinput, $ext = 'png', $fileoutput = '', $page = '') { global $langs; - if (class_exists('Imagick')) { - $image=new Imagick(); + $image=new Imagick(); try { - $ret = $image->readImage($fileinput); + $filetoconvert=$fileinput.(($page != '')?'['.$page.']':''); + //var_dump($filetoconvert); + $ret = $image->readImage($filetoconvert); } catch(Exception $e) { - dol_syslog("Failed to read image using Imagick. Try to install package 'apt-get install ghostscript'.", LOG_WARNING); + $ext = pathinfo($fileinput, PATHINFO_EXTENSION); + dol_syslog("Failed to read image using Imagick (Try to install package 'apt-get install php-imagick ghostscript' and check there is no policy to disable ".$ext." convertion in /etc/ImageMagick*/policy.xml): ".$e->getMessage(), LOG_WARNING); return 0; } if ($ret) { - $ret = $image->setImageFormat($ext); + $ret = $image->setImageFormat($ext); if ($ret) { if (empty($fileoutput)) $fileoutput=$fileinput.".".$ext; $count = $image->getNumberImages(); + if (! dol_is_file($fileoutput) || is_writeable($fileoutput)) { - try { - $ret = $image->writeImages($fileoutput, true); - } - catch(Exception $e) - { - dol_syslog($e->getMessage(), LOG_WARNING); - } + $ret = $image->writeImages($fileoutput, true); } else { @@ -1885,26 +1890,89 @@ function dol_convert_file($fileinput, $ext='png', $fileoutput='') * @param string $mode 'gz' or 'bz' or 'zip' * @return int <0 if KO, >0 if OK */ -function dol_compress_file($inputfile, $outputfile, $mode="gz") +function dol_compress_file($inputfile, $outputfile, $mode = "gz") { + global $conf; + $foundhandler=0; try { + dol_syslog("dol_compress_file mode=".$mode." inputfile=".$inputfile." outputfile=".$outputfile); + $data = implode("", file(dol_osencode($inputfile))); if ($mode == 'gz') { $foundhandler=1; $compressdata = gzencode($data, 9); } elseif ($mode == 'bz') { $foundhandler=1; $compressdata = bzcompress($data, 9); } elseif ($mode == 'zip') { + if (class_exists('ZipArchive') && ! empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_COMPRESS)) + { + $foundhandler=1; + + $rootPath = realpath($inputfile); + + dol_syslog("Class ZipArchive is set so we zip using ZipArchive to zip into ".$outputfile.' rootPath='.$rootPath); + $zip = new ZipArchive; + + if ($zip->open($outputfile, ZipArchive::CREATE) !== true) { + $errormsg="Failed to open file ".$outputfile."\n"; + dol_syslog("dol_compress_file failure - ".$errormsg, LOG_ERR); + return -6; + } + + // Create recursive directory iterator + /** @var SplFileInfo[] $files */ + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($rootPath), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($files as $name => $file) + { + // Skip directories (they would be added automatically) + if (!$file->isDir()) + { + // Get real and relative path for current file + $filePath = $file->getRealPath(); + $relativePath = substr($filePath, strlen($rootPath) + 1); + + // Add current file to archive + $zip->addFile($filePath, $relativePath); + } + } + + // Zip archive will be created only after closing object + $zip->close(); + + dol_syslog("dol_compress_file success - ".count($zip->numFiles)." files"); + return 1; + } + if (defined('ODTPHP_PATHTOPCLZIP')) { $foundhandler=1; include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; $archive = new PclZip($outputfile); - $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); - //$archive->add($inputfile); - return 1; + $result = $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); + + if ($result === 0) + { + global $errormsg; + $errormsg=$archive->errorInfo(true); + dol_syslog("dol_compress_file failure - ".$errormsg, LOG_ERR); + if ($archive->errorCode() == PCLZIP_ERR_WRITE_OPEN_FAIL) + { + dol_syslog("dol_compress_file error PCLZIP_ERR_WRITE_OPEN_FAIL", LOG_ERR); + return -4; + } + return -3; + } + else + { + dol_syslog("dol_compress_file success - ".count($result)." files"); + return 1; + } } } @@ -1917,7 +1985,7 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") } else { - dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); + dol_syslog("Try to zip with format ".$mode." with no handler for this format", LOG_ERR); return -2; } } @@ -1925,7 +1993,7 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") { global $langs, $errormsg; $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); $errormsg=$langs->trans("ErrorFailedToWriteInDir"); return -1; } @@ -1938,11 +2006,11 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") * @param string $outputdir Target dir name * @return array array('error'=>'Error code') or array() if no error */ -function dol_uncompress($inputfile,$outputdir) +function dol_uncompress($inputfile, $outputdir) { - global $langs; + global $conf, $langs; - if (defined('ODTPHP_PATHTOPCLZIP')) + if (defined('ODTPHP_PATHTOPCLZIP') && empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_UNCOMPRESS)) { dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir); include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; @@ -1997,9 +2065,10 @@ function dol_uncompress($inputfile,$outputdir) * @param string $inputdir Source dir name * @param string $outputfile Target file name (output directory must exists and be writable) * @param string $mode 'zip' + * @param string $excludefiles A regex pattern. For example: '/\.log$|\/temp\//' * @return int <0 if KO, >0 if OK */ -function dol_compress_dir($inputdir, $outputfile, $mode="zip") +function dol_compress_dir($inputdir, $outputfile, $mode = "zip", $excludefiles = '') { $foundhandler=0; @@ -2009,7 +2078,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") { global $langs, $errormsg; $langs->load("errors"); - $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); + $errormsg=$langs->trans("ErrorFailedToWriteInDir", $outputfile); return -3; } @@ -2030,6 +2099,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") return 1; } else*/ + //if (class_exists('ZipArchive') && ! empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_COMPRESS)) if (class_exists('ZipArchive')) { $foundhandler=1; @@ -2037,6 +2107,13 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") // Initialize archive object $zip = new ZipArchive(); $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); + if (! $result) + { + global $langs, $errormsg; + $langs->load("errors"); + $errormsg=$langs->trans("ErrorFailedToWriteInFile", $outputfile); + return -4; + } // Create recursive directory iterator /** @var SplFileInfo[] $files */ @@ -2053,9 +2130,11 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") // Get real and relative path for current file $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($inputdir) + 1); - - // Add current file to archive - $zip->addFile($filePath, $relativePath); + if (empty($excludefiles) || ! preg_match($excludefiles, $filePath)) + { + // Add current file to archive + $zip->addFile($filePath, $relativePath); + } } } @@ -2068,7 +2147,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") if (! $foundhandler) { - dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); + dol_syslog("Try to zip with format ".$mode." with no handler for this format", LOG_ERR); return -2; } else @@ -2082,7 +2161,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") $langs->load("errors"); dol_syslog("Failed to open file ".$outputfile, LOG_ERR); dol_syslog($e->getMessage(), LOG_ERR); - $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); + $errormsg=$langs->trans("ErrorFailedToWriteInDir", $outputfile); return -1; } } @@ -2099,9 +2178,9 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only * @return string Full path to most recent file */ -function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta|_preview.*\.png)$','^\.'),$nohook=false,$mode='') +function dol_most_recent_file($dir, $regexfilter = '', $excludefilter = array('(\.meta|_preview.*\.png)$','^\.'), $nohook = false, $mode = '') { - $tmparray=dol_dir_list($dir,'files',0,$regexfilter,$excludefilter,'date',SORT_DESC,$mode,$nohook); + $tmparray=dol_dir_list($dir, 'files', 0, $regexfilter, $excludefilter, 'date', SORT_DESC, $mode, $nohook); return $tmparray[0]; } @@ -2115,9 +2194,9 @@ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta * @param string $refname Ref of object to check permission for external users (autodetect if not provided) * @param string $mode Check permission for 'read' or 'write' * @return mixed Array with access information : 'accessallowed' & 'sqlprotectagainstexternals' & 'original_file' (as a full path name) - * @see restrictedArea + * @see restrictedArea() */ -function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser='', $refname='', $mode='read') +function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser = '', $refname = '', $mode = 'read') { global $conf, $db, $user; global $dolibarr_main_data_root, $dolibarr_main_document_root_alt; @@ -2134,6 +2213,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if ($modulepart == 'users') $modulepart='user'; dol_syslog('modulepart='.$modulepart.' original_file='.$original_file.' entity='.$entity); + // We define $accessallowed and $sqlprotectagainstexternals $accessallowed=0; $sqlprotectagainstexternals=''; @@ -2142,8 +2222,6 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Find the subdirectory name as the reference. For exemple original_file='10/myfile.pdf' -> refname='10' if (empty($refname)) $refname=basename(dirname($original_file)."/"); - $relative_original_file = $original_file; - // Define possible keys to use for permission check $lire='lire'; $read='read'; $download='download'; if ($mode == 'write') @@ -2293,7 +2371,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $original_file=$conf->adherent->dir_temp.'/'.$original_file; } // Wrapping pour les images des stats produits - elseif (preg_match('/^productstats_/i',$modulepart) && !empty($conf->product->dir_temp)) + elseif (preg_match('/^productstats_/i', $modulepart) && !empty($conf->product->dir_temp)) { if ($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) $accessallowed=1; $original_file=(!empty($conf->product->multidir_temp[$entity])?$conf->product->multidir_temp[$entity]:$conf->service->multidir_temp[$entity]).'/'.$original_file; @@ -2320,7 +2398,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping pour les prelevements elseif ($modulepart == 'prelevement' && !empty($conf->prelevement->dir_output)) { - if ($fuser->rights->prelevement->bons->{$lire} || preg_match('/^specimen/i',$original_file)) $accessallowed=1; + if ($fuser->rights->prelevement->bons->{$lire} || preg_match('/^specimen/i', $original_file)) $accessallowed=1; $original_file=$conf->prelevement->dir_output.'/'.$original_file; } // Wrapping pour les graph energie @@ -2369,11 +2447,11 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for users - else if ($modulepart == 'user' && !empty($conf->user->dir_output)) + elseif ($modulepart == 'user' && !empty($conf->user->dir_output)) { $canreaduser=(! empty($fuser->admin) || $fuser->rights->user->user->{$lire}); if ($fuser->id == (int) $refname) { $canreaduser=1; } // A user can always read its own card - if ($canreaduser || preg_match('/^specimen/i',$original_file)) + if ($canreaduser || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2381,10 +2459,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for third parties - else if (($modulepart == 'company' || $modulepart == 'societe') && !empty($conf->societe->dir_output)) + elseif (($modulepart == 'company' || $modulepart == 'societe' || $modulepart == 'thirdparty') && !empty($conf->societe->dir_output)) { if (empty($entity) || empty($conf->societe->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); - if ($fuser->rights->societe->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->societe->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2393,7 +2471,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for contact - else if ($modulepart == 'contact' && !empty($conf->societe->dir_output)) + elseif ($modulepart == 'contact' && !empty($conf->societe->dir_output)) { if (empty($entity) || empty($conf->societe->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); if ($fuser->rights->societe->{$lire}) @@ -2404,9 +2482,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for invoices - else if (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output)) + elseif (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output)) { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2414,73 +2492,73 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping for mass actions - else if ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->multidir_output[$entity])) + elseif ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->multidir_output[$entity])) { - if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->propal->multidir_output[$entity].'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_orders') + elseif ($modulepart == 'massfilesarea_orders') { - if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_invoices') + elseif ($modulepart == 'massfilesarea_invoices') { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_expensereport') + elseif ($modulepart == 'massfilesarea_expensereport') { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_interventions') + elseif ($modulepart == 'massfilesarea_interventions') { - if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->supplier_proposal->dir_output)) + elseif ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->supplier_proposal->dir_output)) { - if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_supplier_order') + elseif ($modulepart == 'massfilesarea_supplier_order') { - if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_supplier_invoice') + elseif ($modulepart == 'massfilesarea_supplier_invoice') { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output)) + elseif ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output)) { - if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2488,9 +2566,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for interventions - else if (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) + elseif (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) { - if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2499,9 +2577,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les deplacements et notes de frais - else if ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output)) + elseif ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output)) { - if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2509,9 +2587,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, //$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping pour les propales - else if (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity])) + elseif (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity])) { - if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2520,9 +2598,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les commandes - else if (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output)) + elseif (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output)) { - if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2531,18 +2609,18 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les projets - else if ($modulepart == 'project' && !empty($conf->projet->dir_output)) + elseif ($modulepart == 'project' && !empty($conf->projet->dir_output)) { - if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->projet->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")"; } - else if ($modulepart == 'project_task' && !empty($conf->projet->dir_output)) + elseif ($modulepart == 'project_task' && !empty($conf->projet->dir_output)) { - if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2551,9 +2629,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les commandes fournisseurs - else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) + elseif (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) { - if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2562,19 +2640,19 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les factures fournisseurs - else if (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output)) + elseif (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output)) { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file; - $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE facnumber='".$db->escape($refname)."' AND entity=".$conf->entity; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping pour les rapport de paiements - else if ($modulepart == 'supplier_payment') + elseif ($modulepart == 'supplier_payment') { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2583,9 +2661,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les rapport de paiements - else if ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output)) + elseif ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output)) { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2594,9 +2672,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for accounting exports - else if ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output)) + elseif ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output)) { - if ($fuser->rights->accounting->bind->write || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->accounting->bind->write || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2604,18 +2682,18 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les expedition - else if ($modulepart == 'expedition' && !empty($conf->expedition->dir_output)) + elseif ($modulepart == 'expedition' && !empty($conf->expedition->dir_output)) { - if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->expedition->dir_output."/sending/".$original_file; } // Wrapping pour les bons de livraison - else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) + elseif ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) { - if ($fuser->rights->expedition->livraison->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->expedition->livraison->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2623,9 +2701,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les actions - else if ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) + elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) { - if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2633,9 +2711,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les actions - else if ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp)) + elseif ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp)) { - if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2643,10 +2721,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les produits et services - else if ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') + elseif ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') { 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'); - if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i',$original_file)) + if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2655,20 +2733,31 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les lots produits - else if ($modulepart == 'product_batch' || $modulepart == 'produitlot') + elseif ($modulepart == 'product_batch' || $modulepart == 'produitlot') { if (empty($entity) || (empty($conf->productbatch->multidir_output[$entity]))) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); - if (($fuser->rights->produit->{$lire} ) || preg_match('/^specimen/i',$original_file)) + if (($fuser->rights->produit->{$lire} ) || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } if (! empty($conf->productbatch->enabled)) $original_file=$conf->productbatch->multidir_output[$entity].'/'.$original_file; } - // Wrapping pour les contrats - else if ($modulepart == 'contract' && !empty($conf->contrat->dir_output)) + // Wrapping for stock movements + elseif ($modulepart == 'movement' || $modulepart == 'mouvement') { - if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file)) + if (empty($entity) || empty($conf->stock->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); + if (($fuser->rights->stock->{$lire} || $fuser->rights->stock->movement->{$lire} || $fuser->rights->stock->mouvement->{$lire}) || preg_match('/^specimen/i', $original_file)) + { + $accessallowed=1; + } + if (! empty($conf->stock->enabled)) $original_file=$conf->stock->multidir_output[$entity].'/movement/'.$original_file; + } + + // Wrapping pour les contrats + elseif ($modulepart == 'contract' && !empty($conf->contrat->dir_output)) + { + if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2677,9 +2766,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les dons - else if ($modulepart == 'donation' && !empty($conf->don->dir_output)) + elseif ($modulepart == 'donation' && !empty($conf->don->dir_output)) { - if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2687,9 +2776,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les dons - else if ($modulepart == 'dolresource' && !empty($conf->resource->dir_output)) + elseif ($modulepart == 'dolresource' && !empty($conf->resource->dir_output)) { - if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2697,9 +2786,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les remises de cheques - else if ($modulepart == 'remisecheque' && !empty($conf->banque->dir_output)) + elseif ($modulepart == 'remisecheque' && !empty($conf->bank->dir_output)) { - if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2708,7 +2797,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for bank - else if ($modulepart == 'bank' && !empty($conf->bank->dir_output)) + elseif (($modulepart == 'banque' || $modulepart == 'bank') && !empty($conf->bank->dir_output)) { if ($fuser->rights->banque->{$lire}) { @@ -2718,7 +2807,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for export module - else if ($modulepart == 'export' && !empty($conf->export->dir_temp)) + elseif ($modulepart == 'export' && !empty($conf->export->dir_temp)) { // Aucun test necessaire car on force le rep de download sur // le rep export qui est propre a l'utilisateur @@ -2727,35 +2816,35 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for import module - else if ($modulepart == 'import' && !empty($conf->import->dir_temp)) + elseif ($modulepart == 'import' && !empty($conf->import->dir_temp)) { $accessallowed=1; $original_file=$conf->import->dir_temp.'/'.$original_file; } // Wrapping pour l'editeur wysiwyg - else if ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output)) + elseif ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output)) { $accessallowed=1; $original_file=$conf->fckeditor->dir_output.'/'.$original_file; } // Wrapping for backups - else if ($modulepart == 'systemtools' && !empty($conf->admin->dir_output)) + elseif ($modulepart == 'systemtools' && !empty($conf->admin->dir_output)) { if ($fuser->admin) $accessallowed=1; $original_file=$conf->admin->dir_output.'/'.$original_file; } // Wrapping for upload file test - else if ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp)) + elseif ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp)) { if ($fuser->admin) $accessallowed=1; $original_file=$conf->admin->dir_temp.'/'.$original_file; } // Wrapping pour BitTorrent - else if ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output)) + elseif ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output)) { $accessallowed=1; $dir='files'; @@ -2764,9 +2853,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour Foundation module - else if ($modulepart == 'member' && !empty($conf->adherent->dir_output)) + elseif ($modulepart == 'member' && !empty($conf->adherent->dir_output)) { - if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2774,7 +2863,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for Scanner - else if ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp)) + elseif ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp)) { $accessallowed=1; $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file; @@ -2787,45 +2876,58 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart else { - 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. + 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. if ($fuser->admin) $accessallowed=1; // If user is admin // Define $accessallowed - if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg)) + if (preg_match('/^([a-z]+)_user_temp$/i', $modulepart, $reg)) { if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file; } - else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg)) + elseif (preg_match('/^([a-z]+)_temp$/i', $modulepart, $reg)) { if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file; } - else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg)) + elseif (preg_match('/^([a-z]+)_user$/i', $modulepart, $reg)) { if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file; } + elseif (preg_match('/^massfilesarea_([a-z]+)$/i', $modulepart, $reg)) + { + if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported + { + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + exit; + } + if ($fuser->rights->{$reg[1]}->{$lire} || preg_match('/^specimen/i', $original_file)) + { + $accessallowed=1; + } + $original_file=$conf->{$reg[1]}->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + } else { if (empty($conf->$modulepart->dir_output)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } @@ -2971,4 +3073,3 @@ function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathre return $file_list; } -