diff --git a/admin_settings.php b/admin_settings.php index 49e2bd8c..538df344 100644 --- a/admin_settings.php +++ b/admin_settings.php @@ -290,6 +290,38 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { } eval("echo \"" . getTemplate("settings/integritycheck") . "\";"); } +elseif ($page == 'importexport' && $userinfo['change_serversettings'] == '1') +{ + if (isset($_GET['action']) && $_GET['action'] == "export") { + // export + try { + $json_export = SImExporter::export(); + } catch(Exception $e) { + dynamic_error($e->getMessage()); + } + header('Content-disposition: attachment; filename=Froxlor_settings-'.$version.'-'.$dbversion.'_'.date('d.m.Y').'.json'); + header('Content-type: application/json'); + echo $json_export; + exit; + } elseif (isset($_GET['action']) && $_GET['action'] == "import") { + // import + if (isset($_POST['send']) && $_POST['send'] == 'send') { + // get uploaded file + if (isset($_FILES["import_file"]["tmp_name"])) { + $imp_content = file_get_contents($_FILES["import_file"]["tmp_name"]); + try { + SImExporter::import($imp_content); + } catch(Exception $e) { + dynamic_error($e->getMessage()); + } + standard_success('settingsimported', '', array('filename' => 'admin_settings.php')); + } + dynamic_error("Upload failed"); + } + } else { + eval("echo \"" . getTemplate("settings/importexport/index") . "\";"); + } +} elseif ($page == 'testmail') { if (isset($_POST['send']) && $_POST['send'] == 'send') diff --git a/lib/classes/settings/class.SImExporter.php b/lib/classes/settings/class.SImExporter.php new file mode 100644 index 00000000..206f4e1d --- /dev/null +++ b/lib/classes/settings/class.SImExporter.php @@ -0,0 +1,114 @@ + + * @author Froxlor team (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Classes + * + * @since 0.9.39 + * + */ + +/** + * Class SImExporter + * + * Import/Export settings to JSON + * + * @copyright (c) the authors + * @author Michael Kaufmann + * @author Froxlor team (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Classes + */ +class SImExporter +{ + + /** + * settings which are not being exported + * + * @var array + */ + private static $_no_export = [ + 'panel.adminmail', + 'admin.show_news_feed', + 'system.lastaccountnumber', + 'system.lastguid', + 'system.ipaddress', + 'system.last_traffic_run', + 'system.hostname', + 'system.mysql_access_host', + 'system.lastcronrun', + 'system.defaultip', + 'system.last_tasks_run', + 'system.last_archive_run', + 'system.leprivatekey', + 'system.lepublickey' + ]; + + public static function export() + { + $result_stmt = Database::query(" + SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` ORDER BY `settingid` ASC + "); + $_data = array(); + while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { + $index = $row['settinggroup'] . "." . $row['varname']; + if (! in_array($index, self::$_no_export)) { + $_data[$index] = $row['value']; + } + } + // add checksum for validation + $_data['_sha'] = sha1(var_export($_data, true)); + $_export = json_encode($_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + if (! $_export) { + throw new Exception("Error exporting settings: " . json_last_error_msg()); + } + return $_export; + } + + public static function import($json_str = null) + { + // decode data + $_data = json_decode($json_str, true); + if ($_data) { + // get validity check data + $_sha = isset($_data['_sha']) ? $_data['_sha'] : false; + $_version = isset($_data['panel.version']) ? $_data['panel.version'] : false; + $_dbversion = isset($_data['panel.db_version']) ? $_data['panel.db_version'] : false; + // check if we have everything we need + if (! $_sha || ! $_version || ! $_dbversion) { + throw new Exception("Invalid froxlor settings data. Unable to import."); + } + // validate import file + unset($_data['_sha']); + // compare + if ($_sha != sha1(var_export($_data, true))) { + throw new Exception("SHA check of import data failed. Unable to import."); + } + // do not import version info - but we need that to possibily update settings + // when there were changes in the variable-name or similar + unset($_data['panel.version']); + unset($_data['panel.db_version']); + /* + // store new data + foreach ($_data as $index => $value) { + Settings::Set($index, $value); + } + // save to DB + Settings::Flush(); + */ + // all good + return true; + } + throw new Exception("Invalid JSON data: " . json_last_error_msg()); + } +} diff --git a/lib/functions/output/function.standard_error.php b/lib/functions/output/function.standard_error.php index d202a2c4..03fb272f 100644 --- a/lib/functions/output/function.standard_error.php +++ b/lib/functions/output/function.standard_error.php @@ -63,3 +63,15 @@ function standard_error($errors = '', $replacer = '') { eval("echo \"" . getTemplate('misc/error', '1') . "\";"); exit; } + +function dynamic_error($message) { + global $userinfo, $s, $header, $footer, $lng, $theme; + $_SESSION['requestData'] = $_POST; + $link = ''; + if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST']) !== false) { + $link = ''.$lng['panel']['back'].''; + } + $error = $message; + eval("echo \"" . getTemplate('misc/error', '1') . "\";"); + exit; +} diff --git a/lng/english.lng.php b/lng/english.lng.php index bb58842e..64d12df9 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -2101,4 +2101,5 @@ $lng['phpfpm']['ini_values'] = 'Enter possible php_values for p $lng['phpfpm']['ini_admin_flags'] = 'Enter possible php_admin_flags for php.ini. One entry per line'; $lng['phpfpm']['ini_admin_values'] = 'Enter possible php_admin_values for php.ini. One entry per line'; $lng['serversettings']['phpfpm_settings']['envpath'] = 'Paths to add to the PATH environment. Leave empty for no PATH environment variable'; - +$lng['admin']['configfiles']['importexport'] = 'Import/Export'; +$lng['success']['settingsimported'] = 'Settings imported successfully'; diff --git a/lng/german.lng.php b/lng/german.lng.php index b822aa3b..f9d86ab2 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1752,3 +1752,4 @@ $lng['phpfpm']['ini_values'] = 'Mögliche php_values für die p $lng['phpfpm']['ini_admin_flags'] = 'Mögliche php_admin_flags für die php.ini. Pro Zeile eine Direktive'; $lng['phpfpm']['ini_admin_values'] = 'Mögliche php_admin_values für die php.ini. Pro Zeile eine Direktive'; $lng['serversettings']['phpfpm_settings']['envpath'] = 'Pfade für die PATH Umgebungsvariable. Leerlassen, um keine PATH Umgebungsvariable zu setzen.'; +$lng['success']['settingsimported'] = 'Einstellungnen erfolgreich importiert'; diff --git a/templates/Sparkle/admin/settings/importexport/index.tpl b/templates/Sparkle/admin/settings/importexport/index.tpl new file mode 100644 index 00000000..41da2dfb --- /dev/null +++ b/templates/Sparkle/admin/settings/importexport/index.tpl @@ -0,0 +1,26 @@ +$header +
+
+

+   + {$lng['admin']['configfiles']['importexport']} +

+
+ +
+ + + +
+

+
+
+ + + + + +
+
+
+$footer diff --git a/templates/Sparkle/admin/settings/settings.tpl b/templates/Sparkle/admin/settings/settings.tpl index 7a3075ed..12082722 100644 --- a/templates/Sparkle/admin/settings/settings.tpl +++ b/templates/Sparkle/admin/settings/settings.tpl @@ -3,7 +3,8 @@

  {$lng['admin']['serversettings']}   - [{$lng['admin']['configfiles']['compactoverview']}] + [{$lng['admin']['configfiles']['compactoverview']}]   + [{$lng['admin']['configfiles']['importexport']}]

diff --git a/templates/Sparkle/admin/settings/settings_overview.tpl b/templates/Sparkle/admin/settings/settings_overview.tpl index c1cd32ac..4a59c4c7 100644 --- a/templates/Sparkle/admin/settings/settings_overview.tpl +++ b/templates/Sparkle/admin/settings/settings_overview.tpl @@ -3,7 +3,8 @@

  {$lng['admin']['serversettings']}   - [{$lng['admin']['configfiles']['overview']}] + [{$lng['admin']['configfiles']['overview']}]   + [{$lng['admin']['configfiles']['importexport']}]