diff --git a/ChangeLog b/ChangeLog index 059fc0d145c..4ba65941254 100644 --- a/ChangeLog +++ b/ChangeLog @@ -105,6 +105,7 @@ NEW: Use an ajax call for the clicktodial feature instead of href link. NEW: when multiple order linked to facture, show list into note. NEW: when we delete several objects with massaction, if somes object has child we must see which objects are concerned and nevertheless delete objects which can be deleted NEW: Editing a page in website module keep old page with name .back +NEW: External backups can be downloaded from the "About info page". For developers: diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index a3c7c3d5c08..4122e2b56ed 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -326,6 +326,13 @@ if ($mode == 'desc') { $textexternal = ''; if ($objMod->isCoreOrExternalModule() == 'external') { $textexternal .= '
'.$langs->trans("Origin").': '.$langs->trans("ExternalModule").' - '.$langs->trans("InstalledInto", $dirofmodule); + + global $dolibarr_allow_download_external_modules; + if (!empty($dolibarr_allow_download_external_modules) && preg_match('/\/custom\//', $dirofmodule)) { + // Add a link to download a zip of the module + $textexternal .= ' '.img_picto('', 'download').''; + } + if ($objMod->editor_name != 'dolibarr') { $textexternal .= '
'.$langs->trans("Publisher").': '.(empty($objMod->editor_name) ? $langs->trans("Unknown") : $objMod->editor_name); } diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index ff4b12efc9e..0b9272c2418 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -138,7 +138,23 @@ $dirtocompress = basename($fulldirtocompress); if ($compression == 'zip') { $file .= '.zip'; $excludefiles = '/(\.back|\.old|\.log|[\/\\\]temp[\/\\\]|documents[\/\\\]admin[\/\\\]documents[\/\\\])/i'; - $ret = dol_compress_dir($fulldirtocompress, $outputdir."/".$file, $compression, $excludefiles); + + //var_dump($fulldirtocompress); + //var_dump($outputdir."/".$file);exit; + + $rootdirinzip = ''; + if ($export_type == 'externalmodule' && !empty($what)) { + $rootdirinzip = $what; + + global $dolibarr_allow_download_external_modules; + if (empty($dolibarr_allow_download_external_modules)) { + print 'Download of external modules is not allowed by $dolibarr_allow_download_external_modules in conf.php file'; + $db->close(); + exit(); + } + } + + $ret = dol_compress_dir($fulldirtocompress, $outputdir."/".$file, $compression, $excludefiles, $rootdirinzip); if ($ret < 0) { if ($ret == -2) { $langs->load("errors"); @@ -183,17 +199,37 @@ if ($compression == 'zip') { unlink($outputdir."/".$file); } } -} - -if ($errormsg) { - setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors'); } else { - setEventMessages($langs->trans("BackupFileSuccessfullyCreated").'.
'.$langs->trans("YouCanDownloadBackupFile"), null, 'mesgs'); + $errormsg = 'Bad value for compression method'; + print $errormsg; } -$db->close(); +if ($export_type != 'externalmodule' || empty($what)) { + if ($errormsg) { + setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors'); + } else { + setEventMessages($langs->trans("BackupFileSuccessfullyCreated").'.
'.$langs->trans("YouCanDownloadBackupFile"), null, 'mesgs'); + } -// Redirect to calling page -$returnto = 'dolibarr_export.php'; + $db->close(); -header("Location: ".$returnto); + // Redirect to calling page + $returnto = 'dolibarr_export.php'; + + header("Location: ".$returnto); + exit(); +} else { + $zipname = $outputdir."/".$file; + + // Then download the zipped file. + header('Content-Type: application/zip'); + header('Content-disposition: attachment; filename='.basename($zipname)); + header('Content-Length: '.filesize($zipname)); + readfile($zipname); + + dol_delete_file($zipname); + + $db->close(); + + exit(); +} diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 855505a40ec..1f821bf733b 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -499,7 +499,7 @@ if ($result && $action == "dl" && !$error) { $zip->addFromString('transactions.csv', $log); $zip->close(); - ///Then download the zipped file. + // Then download the zipped file. header('Content-Type: application/zip'); header('Content-disposition: attachment; filename='.basename($zipname)); header('Content-Length: '.filesize($zipname)); diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index 71f0a82e32f..7bb58d6b701 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -331,6 +331,12 @@ $dolibarr_cron_allow_cli='0'; // Examples: // $dolibarr_strict_mode=0; +// dolibarr_allow_download_external_modules +// Provide a link to download the zip of an external modules installed into custom directory from the web admin. +// Default value: 0 +// Examples: +// $dolibarr_allow_download_external_modules=0; + //################################# diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 2bd4ada3ad0..7312faf6b5e 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2004,11 +2004,15 @@ function dol_compress_file($inputfile, $outputfile, $mode = "gz", &$errorstring // 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); + $filePath = $file->getPath(); // the full path with filename using the $inputdir root. + $fileName = $file->getFilename(); + $fileFullRealPath = $file->getRealPath(); // the full path with name and transformed to use real path directory. + + //$relativePath = substr($fileFullRealPath, strlen($rootPath) + 1); + $relativePath = substr(($filePath ? $filePath.'/' : '').$fileName, strlen($rootPath) + 1); // Add current file to archive - $zip->addFile($filePath, $relativePath); + $zip->addFile($fileFullRealPath, $relativePath); } } @@ -2196,22 +2200,29 @@ function dol_compress_dir($inputdir, $outputfile, $mode = "zip", $excludefiles = } // Create recursive directory iterator + // This does not return symbolic links /** @var SplFileInfo[] $files */ $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($inputdir), RecursiveIteratorIterator::LEAVES_ONLY ); + //var_dump($inputdir); 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 = ($rootdirinzip ? $rootdirinzip.'/' : '').substr($filePath, strlen($inputdir) + 1); + $filePath = $file->getPath(); // the full path with filename using the $inputdir root. + $fileName = $file->getFilename(); + $fileFullRealPath = $file->getRealPath(); // the full path with name and transformed to use real path directory. - if (empty($excludefiles) || !preg_match($excludefiles, $filePath)) { + //$relativePath = ($rootdirinzip ? $rootdirinzip.'/' : '').substr($fileFullRealPath, strlen($inputdir) + 1); + $relativePath = ($rootdirinzip ? $rootdirinzip.'/' : '').substr(($filePath ? $filePath.'/' : '').$fileName, strlen($inputdir) + 1); + + //var_dump($filePath);var_dump($fileFullRealPath);var_dump($relativePath); + if (empty($excludefiles) || !preg_match($excludefiles, $fileFullRealPath)) { // Add current file to archive - $zip->addFile($filePath, $relativePath); + $zip->addFile($fileFullRealPath, $relativePath); } } }