Browse Source

External backups can be downloaded from the "About info page".

Laurent Destailleur 3 years ago
parent
commit
2d92130c1e

+ 1 - 0
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:

+ 7 - 0
htdocs/admin/modulehelp.php

@@ -326,6 +326,13 @@ if ($mode == 'desc') {
 	$textexternal = '';
 	if ($objMod->isCoreOrExternalModule() == 'external') {
 		$textexternal .= '<br><span class="opacitymedium">'.$langs->trans("Origin").':</span> '.$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 .= ' <a href="'.DOL_URL_ROOT.'/admin/tools/export_files.php?export_type=externalmodule&what='.urlencode($moduledir).'&compression=zip&zipfilename_template=module_'.$moduledir.'-'.$version.'.notorig" target="_blank" rel="noopener">'.img_picto('', 'download').'</a>';
+		}
+
 		if ($objMod->editor_name != 'dolibarr') {
 			$textexternal .= '<br><span class="opacitymedium">'.$langs->trans("Publisher").':</span> '.(empty($objMod->editor_name) ? $langs->trans("Unknown") : $objMod->editor_name);
 		}

+ 45 - 9
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);
 		}
 	}
+} else {
+	$errormsg = 'Bad value for compression method';
+	print $errormsg;
 }
 
-if ($errormsg) {
-	setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors');
+if ($export_type != 'externalmodule' || empty($what)) {
+	if ($errormsg) {
+		setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors');
+	} else {
+		setEventMessages($langs->trans("BackupFileSuccessfullyCreated").'.<br>'.$langs->trans("YouCanDownloadBackupFile"), null, 'mesgs');
+	}
+
+	$db->close();
+
+	// Redirect to calling page
+	$returnto = 'dolibarr_export.php';
+
+	header("Location: ".$returnto);
+	exit();
 } else {
-	setEventMessages($langs->trans("BackupFileSuccessfullyCreated").'.<br>'.$langs->trans("YouCanDownloadBackupFile"), null, 'mesgs');
-}
+	$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);
 
-$db->close();
+	dol_delete_file($zipname);
 
-// Redirect to calling page
-$returnto = 'dolibarr_export.php';
+	$db->close();
 
-header("Location: ".$returnto);
+	exit();
+}

+ 1 - 1
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));

+ 6 - 0
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;
+
 
 
 //#################################

+ 18 - 7
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.
+
+						//$relativePath = ($rootdirinzip ? $rootdirinzip.'/' : '').substr($fileFullRealPath, strlen($inputdir) + 1);
+						$relativePath = ($rootdirinzip ? $rootdirinzip.'/' : '').substr(($filePath ? $filePath.'/' : '').$fileName, strlen($inputdir) + 1);
 
-						if (empty($excludefiles) || !preg_match($excludefiles, $filePath)) {
+						//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);
 						}
 					}
 				}