diff --git a/customer_extras.php b/customer_extras.php
index 06a27a09..96907cb3 100644
--- a/customer_extras.php
+++ b/customer_extras.php
@@ -16,7 +16,6 @@
* @package Panel
*
*/
-
define('AREA', 'customer');
require './lib/init.php';
@@ -38,9 +37,10 @@ if ($page == 'overview') {
);
$paging = new paging($userinfo, TABLE_PANEL_HTPASSWDS, $fields);
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
- WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()
- );
- Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid']));
+ WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
+ Database::pexecute($result_stmt, array(
+ "customerid" => $userinfo['customerid']
+ ));
$paging->setEntries(Database::num_rows());
$sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
@@ -58,38 +58,49 @@ if ($page == 'overview') {
$row['path'] = makeCorrectDir($row['path']);
$row = htmlentities_array($row);
eval("\$htpasswds.=\"" . getTemplate("extras/htpasswds_htpasswd") . "\";");
- $count++;
+ $count ++;
}
- $i++;
+ $i ++;
}
eval("echo \"" . getTemplate("extras/htpasswds") . "\";");
} elseif ($action == 'delete' && $id != 0) {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
WHERE `customerid`= :customerid
- AND `id`= :id"
- );
- Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id));
+ AND `id`= :id");
+ Database::pexecute($result_stmt, array(
+ "customerid" => $userinfo['customerid'],
+ "id" => $id
+ ));
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if (isset($result['username']) && $result['username'] != '') {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTPASSWDS . "`
WHERE `customerid`= :customerid
- AND `id`= :id"
- );
- Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id));
+ AND `id`= :id");
+ Database::pexecute($stmt, array(
+ "customerid" => $userinfo['customerid'],
+ "id" => $id
+ ));
$log->logAction(USR_ACTION, LOG_INFO, "deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
inserttask('1');
- redirectTo($filename, array('page' => $page, 's' => $s));
+ redirectTo($filename, array(
+ 'page' => $page,
+ 's' => $s
+ ));
} else {
if (strpos($result['path'], $userinfo['documentroot']) === 0) {
- $result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']);
+ $result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']);
}
- ask_yesno('extras_reallydelete', $filename, array('id' => $id, 'page' => $page, 'action' => $action), $result['username'] . ' (' . $result['path'] . ')');
+ ask_yesno('extras_reallydelete', $filename, array(
+ 'id' => $id,
+ 'page' => $page,
+ 'action' => $action
+ ), $result['username'] . ' (' . $result['path'] . ')');
}
}
} elseif ($action == 'add') {
@@ -104,8 +115,7 @@ if ($page == 'overview') {
$username_path_check_stmt = Database::prepare("SELECT `id`, `username`, `path` FROM `" . TABLE_PANEL_HTPASSWDS . "`
WHERE `username`= :username
AND `path`= :path
- AND `customerid`= :customerid"
- );
+ AND `customerid`= :customerid");
$params = array(
"username" => $username,
"path" => $path,
@@ -121,16 +131,22 @@ if ($page == 'overview') {
$password = crypt($_POST['directory_password']);
}
- if (!$_POST['path']) {
+ if (! $_POST['path']) {
standard_error('invalidpath');
}
if ($username == '') {
- standard_error(array('stringisempty', 'myloginname'));
+ standard_error(array(
+ 'stringisempty',
+ 'myloginname'
+ ));
} elseif ($username_path_check['username'] == $username && $username_path_check['path'] == $path) {
standard_error('userpathcombinationdupe');
} elseif ($_POST['directory_password'] == '') {
- standard_error(array('stringisempty', 'mypassword'));
+ standard_error(array(
+ 'stringisempty',
+ 'mypassword'
+ ));
} elseif ($path == '') {
standard_error('patherror');
} elseif ($_POST['directory_password'] == $username) {
@@ -141,8 +157,7 @@ if ($page == 'overview') {
`username` = :username,
`password` = :password,
`path` = :path,
- `authname` = :authname"
- );
+ `authname` = :authname");
$params = array(
"customerid" => $userinfo['customerid'],
"username" => $username,
@@ -153,12 +168,15 @@ if ($page == 'overview') {
Database::pexecute($stmt, $params);
$log->logAction(USR_ACTION, LOG_INFO, "added htpasswd for '" . $username . " (" . $path . ")'");
inserttask('1');
- redirectTo($filename, array('page' => $page, 's' => $s));
+ redirectTo($filename, array(
+ 'page' => $page,
+ 's' => $s
+ ));
}
} else {
$pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']);
- $htpasswd_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htpasswd_add.php';
+ $htpasswd_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htpasswd_add.php';
$htpasswd_add_form = htmlform::genHTMLForm($htpasswd_add_data);
$title = $htpasswd_add_data['htpasswd_add']['title'];
@@ -169,9 +187,11 @@ if ($page == 'overview') {
} elseif ($action == 'edit' && $id != 0) {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTPASSWDS . "`
WHERE `customerid`= :customerid
- AND `id`= :id"
- );
- Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id));
+ AND `id`= :id");
+ Database::pexecute($result_stmt, array(
+ "customerid" => $userinfo['customerid'],
+ "id" => $id
+ ));
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if (isset($result['username']) && $result['username'] != '') {
@@ -208,19 +228,21 @@ if ($page == 'overview') {
}
if ($pwd_sql != '' || $auth_sql != '') {
- if ($pwd_sql !='' && $auth_sql != '') {
- $pwd_sql.= ', ';
+ if ($pwd_sql != '' && $auth_sql != '') {
+ $pwd_sql .= ', ';
}
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_HTPASSWDS . "`
- SET ".$pwd_sql.$auth_sql."
+ SET " . $pwd_sql . $auth_sql . "
WHERE `customerid`= :customerid
- AND `id`= :id"
- );
+ AND `id`= :id");
Database::pexecute($stmt, $params);
$log->logAction(USR_ACTION, LOG_INFO, "edited htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
inserttask('1');
- redirectTo($filename, array('page' => $page, 's' => $s));
+ redirectTo($filename, array(
+ 'page' => $page,
+ 's' => $s
+ ));
}
} else {
if (strpos($result['path'], $userinfo['documentroot']) === 0) {
@@ -229,7 +251,7 @@ if ($page == 'overview') {
$result = htmlentities_array($result);
- $htpasswd_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htpasswd_edit.php';
+ $htpasswd_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htpasswd_edit.php';
$htpasswd_edit_form = htmlform::genHTMLForm($htpasswd_edit_data);
$title = $htpasswd_edit_data['htpasswd_edit']['title'];
@@ -252,9 +274,10 @@ if ($page == 'overview') {
);
$paging = new paging($userinfo, TABLE_PANEL_HTACCESS, $fields);
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
- WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit()
- );
- Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid']));
+ WHERE `customerid`= :customerid " . $paging->getSqlWhere(true) . " " . $paging->getSqlOrderBy() . " " . $paging->getSqlLimit());
+ Database::pexecute($result_stmt, array(
+ "customerid" => $userinfo['customerid']
+ ));
$paging->setEntries(Database::num_rows());
$sortcode = $paging->getHtmlSortCode($lng);
$arrowcode = $paging->getHtmlArrowCode($filename . '?page=' . $page . '&s=' . $s);
@@ -278,49 +301,60 @@ if ($page == 'overview') {
$row['options_cgi'] = str_replace('0', $lng['panel']['no'], $row['options_cgi']);
$row = htmlentities_array($row);
eval("\$htaccess.=\"" . getTemplate("extras/htaccess_htaccess") . "\";");
- $count++;
+ $count ++;
}
- $i++;
+ $i ++;
}
eval("echo \"" . getTemplate("extras/htaccess") . "\";");
} elseif ($action == 'delete' && $id != 0) {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `customerid` = :customerid
- AND `id` = :id"
- );
- Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id));
+ AND `id` = :id");
+ Database::pexecute($result_stmt, array(
+ "customerid" => $userinfo['customerid'],
+ "id" => $id
+ ));
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if (isset($result['customerid']) && $result['customerid'] != '' && $result['customerid'] == $userinfo['customerid']) {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
// do we have to remove the symlink and folder in suexecpath?
- if ((int)Settings::Get('perl.suexecworkaround') == 1) {
+ if ((int) Settings::Get('perl.suexecworkaround') == 1) {
$loginname = getCustomerDetail($result['customerid'], 'loginname');
- $suexecpath = makeCorrectDir(Settings::Get('perl.suexecpath').'/'.$loginname.'/'.md5($result['path']).'/');
- $perlsymlink = makeCorrectFile($result['path'].'/cgi-bin');
+ $suexecpath = makeCorrectDir(Settings::Get('perl.suexecpath') . '/' . $loginname . '/' . md5($result['path']) . '/');
+ $perlsymlink = makeCorrectFile($result['path'] . '/cgi-bin');
// remove symlink
if (file_exists($perlsymlink)) {
- safe_exec('rm -f '.escapeshellarg($perlsymlink));
+ safe_exec('rm -f ' . escapeshellarg($perlsymlink));
$log->logAction(USR_ACTION, LOG_DEBUG, "deleted suexecworkaround symlink '" . $perlsymlink . "'");
}
// remove folder in suexec-path
if (file_exists($suexecpath)) {
- safe_exec('rm -rf '.escapeshellarg($suexecpath));
+ safe_exec('rm -rf ' . escapeshellarg($suexecpath));
$log->logAction(USR_ACTION, LOG_DEBUG, "deleted suexecworkaround path '" . $suexecpath . "'");
}
}
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `customerid`= :customerid
- AND `id`= :id"
- );
- Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id));
+ AND `id`= :id");
+ Database::pexecute($stmt, array(
+ "customerid" => $userinfo['customerid'],
+ "id" => $id
+ ));
$log->logAction(USR_ACTION, LOG_INFO, "deleted htaccess for '" . str_replace($userinfo['documentroot'], '/', $result['path']) . "'");
inserttask('1');
- redirectTo($filename, array('page' => $page, 's' => $s));
+ redirectTo($filename, array(
+ 'page' => $page,
+ 's' => $s
+ ));
} else {
- ask_yesno('extras_reallydelete_pathoptions', $filename, array('id' => $id, 'page' => $page, 'action' => $action), str_replace($userinfo['documentroot'], '/', $result['path']));
+ ask_yesno('extras_reallydelete_pathoptions', $filename, array(
+ 'id' => $id,
+ 'page' => $page,
+ 'action' => $action
+ ), str_replace($userinfo['documentroot'], '/', $result['path']));
}
}
} elseif ($action == 'add') {
@@ -330,16 +364,18 @@ if ($page == 'overview') {
$path = makeCorrectDir($userinfo['documentroot'] . '/' . $path);
$path_dupe_check_stmt = Database::prepare("SELECT `id`, `path` FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `path`= :path
- AND `customerid`= :customerid"
- );
- Database::pexecute($path_dupe_check_stmt, array("path" => $path, "customerid" => $userinfo['customerid']));
+ AND `customerid`= :customerid");
+ Database::pexecute($path_dupe_check_stmt, array(
+ "path" => $path,
+ "customerid" => $userinfo['customerid']
+ ));
$path_dupe_check = $path_dupe_check_stmt->fetch(PDO::FETCH_ASSOC);
- if (!$_POST['path']) {
+ if (! $_POST['path']) {
standard_error('invalidpath');
}
- if (isset($_POST['options_cgi']) && (int)$_POST['options_cgi'] != 0) {
+ if (isset($_POST['options_cgi']) && (int) $_POST['options_cgi'] != 0) {
$options_cgi = '1';
} else {
$options_cgi = '0';
@@ -372,8 +408,7 @@ if ($page == 'overview') {
`error404path` = :error404path,
`error403path` = :error403path,
`error500path` = :error500path,
- `options_cgi` = :options_cgi'
- );
+ `options_cgi` = :options_cgi');
$params = array(
"customerid" => $userinfo['customerid'],
"path" => $path,
@@ -387,13 +422,16 @@ if ($page == 'overview') {
$log->logAction(USR_ACTION, LOG_INFO, "added htaccess for '" . $path . "'");
inserttask('1');
- redirectTo($filename, array('page' => $page, 's' => $s));
+ redirectTo($filename, array(
+ 'page' => $page,
+ 's' => $s
+ ));
}
} else {
$pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']);
$cperlenabled = customerHasPerlEnabled($userinfo['customerid']);
- $htaccess_add_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htaccess_add.php';
+ $htaccess_add_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htaccess_add.php';
$htaccess_add_form = htmlform::genHTMLForm($htaccess_add_data);
$title = $htaccess_add_data['htaccess_add']['title'];
@@ -404,9 +442,11 @@ if ($page == 'overview') {
} elseif (($action == 'edit') && ($id != 0)) {
$result_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `customerid` = :customerid
- AND `id` = :id"
- );
- Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'], "id" => $id));
+ AND `id` = :id");
+ Database::pexecute($result_stmt, array(
+ "customerid" => $userinfo['customerid'],
+ "id" => $id
+ ));
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if ((isset($result['customerid'])) && ($result['customerid'] != '') && ($result['customerid'] == $userinfo['customerid'])) {
@@ -426,12 +466,7 @@ if ($page == 'overview') {
$error403path = correctErrorDocument($_POST['error403path']);
$error500path = correctErrorDocument($_POST['error500path']);
- if (($option_indexes != $result['options_indexes'])
- || ($error404path != $result['error404path'])
- || ($error403path != $result['error403path'])
- || ($error500path != $result['error500path'])
- || ($options_cgi != $result['options_cgi'])
- ) {
+ if (($option_indexes != $result['options_indexes']) || ($error404path != $result['error404path']) || ($error403path != $result['error403path']) || ($error500path != $result['error500path']) || ($options_cgi != $result['options_cgi'])) {
inserttask('1');
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_HTACCESS . "`
SET `options_indexes` = :options_indexes,
@@ -440,8 +475,7 @@ if ($page == 'overview') {
`error500path` = :error500path,
`options_cgi` = :options_cgi
WHERE `customerid` = :customerid
- AND `id` = :id"
- );
+ AND `id` = :id");
$params = array(
"customerid" => $userinfo['customerid'],
"options_indexes" => $_POST['options_indexes'] == '1' ? '1' : '0',
@@ -455,7 +489,10 @@ if ($page == 'overview') {
$log->logAction(USR_ACTION, LOG_INFO, "edited htaccess for '" . str_replace($userinfo['documentroot'], '/', $result['path']) . "'");
}
- redirectTo($filename, array('page' => $page, 's' => $s));
+ redirectTo($filename, array(
+ 'page' => $page,
+ 's' => $s
+ ));
} else {
if (strpos($result['path'], $userinfo['documentroot']) === 0) {
$result['path'] = str_replace($userinfo['documentroot'], "/", $result['path']);
@@ -466,12 +503,12 @@ if ($page == 'overview') {
$result['error500path'] = $result['error500path'];
$cperlenabled = customerHasPerlEnabled($userinfo['customerid']);
/*
- $options_indexes = makeyesno('options_indexes', '1', '0', $result['options_indexes']);
- $options_cgi = makeyesno('options_cgi', '1', '0', $result['options_cgi']);
- */
+ * $options_indexes = makeyesno('options_indexes', '1', '0', $result['options_indexes']);
+ * $options_cgi = makeyesno('options_cgi', '1', '0', $result['options_cgi']);
+ */
$result = htmlentities_array($result);
- $htaccess_edit_data = include_once dirname(__FILE__).'/lib/formfields/customer/extras/formfield.htaccess_edit.php';
+ $htaccess_edit_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.htaccess_edit.php';
$htaccess_edit_form = htmlform::genHTMLForm($htaccess_edit_data);
$title = $htaccess_edit_data['htaccess_edit']['title'];
@@ -481,4 +518,66 @@ if ($page == 'overview') {
}
}
}
-}
+} elseif ($page == 'backup') {
+ if ($action == '') {
+ $log->logAction(USR_ACTION, LOG_NOTICE, "viewed customer_extras::backup");
+
+ if (isset($_POST['send']) && $_POST['send'] == 'send') {
+
+ if (! $_POST['path']) {
+ standard_error('invalidpath');
+ }
+
+ $path = makeCorrectDir(validate($_POST['path'], 'path'));
+ $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path);
+
+ $backup_dbs = isset($_POST['backup_dbs']) ? intval($_POST['backup_dbs']) : 0;
+ $backup_mail = isset($_POST['backup_mail']) ? intval($_POST['backup_mail']) : 0;
+ $backup_web = isset($_POST['backup_web']) ? intval($_POST['backup_web']) : 0;
+
+ if ($backup_dbs != '1') {
+ $backup_dbs = '0';
+ }
+
+ if ($backup_mail != '1') {
+ $backup_mail = '0';
+ }
+
+ if ($backup_web != '1') {
+ $backup_web = '0';
+ }
+
+ $task_data = array(
+ 'customerid' => $userinfo['customerid'],
+ 'uid' => $userinfo['guid'],
+ 'gid' => $userinfo['guid'],
+ 'loginname' => $userinfo['loginname'],
+ 'destdir' => $path,
+ 'backup_dbs' => $backup_dbs,
+ 'backup_mail' => $backup_mail,
+ 'backup_web' => $backup_web
+ );
+ inserttask('20', $task_data);
+
+ standard_success('backupscheduled');
+ } else {
+
+ // check whether there is a backup-job for this customer
+ $sel_stmt = Database::prepare("SELECT * FROM `".TABLE_PANEL_TASKS."` WHERE `type` = '20'");
+ Database::pexecute($sel_stmt);
+ while ($entry = $sel_stmt->fetch())
+ {
+ $data = unserialize($entry['data']);
+ if ($data['customerid'] == $userinfo['customerid']) {
+ standard_error('customerhasongoingbackupjob');
+ }
+ }
+ $pathSelect = makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']);
+ $backup_data = include_once dirname(__FILE__) . '/lib/formfields/customer/extras/formfield.backup.php';
+ $backup_form = htmlform::genHTMLForm($backup_data);
+ $title = $backup_data['backup']['title'];
+ $image = $backup_data['backup']['image'];
+ eval("echo \"" . getTemplate("extras/backup") . "\";");
+ }
+ }
+}
\ No newline at end of file
diff --git a/install/froxlor.sql b/install/froxlor.sql
index ae2ec259..5bece437 100644
--- a/install/froxlor.sql
+++ b/install/froxlor.sql
@@ -556,7 +556,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('panel', 'password_special_char_required', '0'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'version', '0.9.35.1'),
- ('panel', 'db_version', '201603150');
+ ('panel', 'db_version', '201604270');
DROP TABLE IF EXISTS `panel_tasks`;
@@ -765,7 +765,8 @@ INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `interval`, `isactive`,
(4, 'froxlor/ticket', 'ticketarchive', '1 MONTH', '1', 'cron_ticketarchive'),
(5, 'froxlor/reports', 'usage_report', '1 DAY', '1', 'cron_usage_report'),
(6, 'froxlor/core', 'mailboxsize', '6 HOUR', '1', 'cron_mailboxsize'),
- (7, 'froxlor/letsencrypt', 'letsencrypt', '5 MINUTE', '0', 'cron_letsencrypt');
+ (7, 'froxlor/letsencrypt', 'letsencrypt', '5 MINUTE', '0', 'cron_letsencrypt'),
+ (8, 'froxlor/backup', 'backup', '1 DAY', '1', 'cron_backup');
diff --git a/install/updates/froxlor/0.9/update_0.9.inc.php b/install/updates/froxlor/0.9/update_0.9.inc.php
index 2b435653..c34c0dc3 100644
--- a/install/updates/froxlor/0.9/update_0.9.inc.php
+++ b/install/updates/froxlor/0.9/update_0.9.inc.php
@@ -3292,3 +3292,21 @@ if (isFroxlorVersion('0.9.35')) {
updateToVersion('0.9.35.1');
}
+
+if (isFroxlorVersion('0.9.35.1') && isDatabaseVersion('201603150')) {
+
+ showUpdateStep("Adding new backup-cron entry");
+ $stmt = Database::prepare("
+ INSERT INTO `" . TABLE_PANEL_CRONRUNS . "` SET
+ `module` = 'froxlor/backup',
+ `cronfile` = 'backup',
+ `interval` = '1 DAY',
+ `desc_lng_key` = 'cron_backup',
+ `lastrun` = 0,
+ `isactive` = 0"
+ );
+ Database::pexecute($stmt);
+ lastStepStatus(0);
+
+ updateToDbVersion('201604270');
+}
diff --git a/lib/formfields/admin/domains/formfield.domains_edit.php b/lib/formfields/admin/domains/formfield.domains_edit.php
index 68ffa009..6837da0a 100644
--- a/lib/formfields/admin/domains/formfield.domains_edit.php
+++ b/lib/formfields/admin/domains/formfield.domains_edit.php
@@ -84,7 +84,7 @@ return array(
'value' => $result['registration_date'],
'size' => 10
),
- 'termination_date' => array(
+ 'termination_date' => array(
'label' => $lng['domains']['termination_date'],
'desc' => $lng['panel']['dateformat'],
'type' => 'text',
diff --git a/lib/formfields/customer/extras/formfield.backup.php b/lib/formfields/customer/extras/formfield.backup.php
new file mode 100644
index 00000000..82c9259b
--- /dev/null
+++ b/lib/formfields/customer/extras/formfield.backup.php
@@ -0,0 +1,70 @@
+ (2010-)
+ * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
+ * @package Formfields
+ *
+ */
+return array(
+ 'backup' => array(
+ 'title' => $lng['extras']['backup'],
+ 'image' => 'icons/backup_big.png',
+ 'sections' => array(
+ 'section_a' => array(
+ 'title' => $lng['extras']['backup'],
+ 'image' => 'icons/backup_big.png',
+ 'fields' => array(
+ 'path' => array(
+ 'label' => $lng['panel']['path'],
+ 'desc' => (Settings::Get('panel.pathedit') != 'Dropdown' ? $lng['panel']['pathDescription'] : null).(isset($pathSelect['note']) ? '
'.$pathSelect['value'] : ''),
+ 'type' => $pathSelect['type'],
+ 'select_var' => $pathSelect['value'],
+ 'value' => $pathSelect['value']
+ ),
+ 'backup_web' => array(
+ 'label' => $lng['extras']['backup_web'],
+ 'type' => 'checkbox',
+ 'values' => array(
+ array(
+ 'label' => $lng['panel']['yes'],
+ 'value' => '1'
+ )
+ ),
+ 'value' => array('1')
+ ),
+ 'backup_mail' => array(
+ 'label' => $lng['extras']['backup_mail'],
+ 'type' => 'checkbox',
+ 'values' => array(
+ array(
+ 'label' => $lng['panel']['yes'],
+ 'value' => '1'
+ )
+ ),
+ 'value' => array('1')
+ ),
+ 'backup_dbs' => array(
+ 'label' => $lng['extras']['backup_dbs'],
+ 'type' => 'checkbox',
+ 'values' => array(
+ array(
+ 'label' => $lng['panel']['yes'],
+ 'value' => '1'
+ )
+ ),
+ 'value' => array('1')
+ )
+ )
+ )
+ )
+ )
+);
diff --git a/lib/functions/filedir/function.createCustomerBackup.php b/lib/functions/filedir/function.createCustomerBackup.php
new file mode 100644
index 00000000..20cff168
--- /dev/null
+++ b/lib/functions/filedir/function.createCustomerBackup.php
@@ -0,0 +1,116 @@
+ (2010-)
+ * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
+ * @package Functions
+ *
+ */
+
+/**
+ * depending on the give choice, the customers web-data, email-data and databases are being backup'ed
+ *
+ * @param array $data
+ *
+ * @return void
+ *
+ */
+function createCustomerBackup($data = null, $customerdocroot = null, &$cronlog)
+{
+ $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating Backup for user "'.$data['loginname'].'"');
+
+ // create tmp folder
+ $tmpdir = makeCorrectDir($data['destdir'] . '/.tmp/');
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating tmp-folder "'.$tmpdir.'"');
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg($tmpdir));
+ safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
+ $create_backup_tar = false;
+
+ // MySQL databases
+ if ($data['backup_dbs'] == 1) {
+
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating mysql-folder "'.makeCorrectDir($tmpdir . '/mysql').'"');
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mysql')));
+ safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mysql')));
+
+ // get all customer database-names
+ $sel_stmt = Database::prepare("SELECT `databasename` FROM `" . TABLE_PANEL_DATABASES . "` WHERE `customerid` = :cid");
+ Database::pexecute($sel_stmt, array(
+ 'cid' => $data['customerid']
+ ));
+
+ Database::needRoot(true);
+ Database::needSqlData();
+ $sql_root = Database::getSqlData();
+ Database::needRoot(false);
+
+ while ($row = $sel_stmt->fetch()) {
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
+ $bool_false = false;
+ safe_exec('mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -p' . $sql_root['passwd'] . ' ' . $row['databasename'] . ' > ' . makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, array('>'));
+ $create_backup_tar = true;
+ }
+
+ unset($sql_root);
+ }
+
+ // E-mail data
+ if ($data['backup_mail'] == 1) {
+
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating mail-folder "'.makeCorrectDir($tmpdir . '/mail').'"');
+ safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/mail')));
+
+ // get all customer mail-accounts
+ $sel_stmt = Database::prepare("SELECT CONCAT(`homedir`, `maildir`) as acc_path FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid` = :cid");
+ Database::pexecute($sel_stmt, array(
+ 'cid' => $data['customerid']
+ ));
+
+ $tar_file_list = "";
+ while ($row = $sel_stmt->fetch()) {
+ $tar_file_list .= $row['acc_path'] . " ";
+ }
+
+ if (! empty($tar_file_list)) {
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' ' . escapeshellarg(trim($tar_file_list)));
+ safe_exec('tar cfz ' . escapeshellarg(makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' ' . escapeshellarg(trim($tar_file_list)));
+ $create_backup_tar = true;
+ }
+ }
+
+ // Web data
+ if ($data['backup_web'] == 1) {
+
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'Creating web-folder "'.makeCorrectDir($tmpdir . '/web').'"');
+ safe_exec('mkdir -p ' . escapeshellarg(makeCorrectDir($tmpdir . '/web')));
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude ' . escapeshellarg($tmpdir) .' ' . escapeshellarg($customerdocroot));
+ safe_exec('tar cfz ' . escapeshellarg(makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude ' . escapeshellarg($tmpdir) .' ' . escapeshellarg($customerdocroot));
+ $create_backup_tar = true;
+ }
+
+ if ($create_backup_tar)
+ {
+ $backup_file = makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-backup_' . date('YmdHi', time()) . '.tar.gz');
+ $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Creating backup-file "'.$backup_file.'"');
+ // pack all archives in tmp-dir to one
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($tmpdir));
+ safe_exec('tar cfz ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($tmpdir));
+ // move to destination directory
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
+ safe_exec('mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
+ // remove tmp-files
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> rm -rf '.escapeshellarg($tmpdir));
+ safe_exec('rm -rf '.escapeshellarg($tmpdir));
+ // set owner to customer
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, 'shell> chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($data['destdir']));
+ safe_exec('chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($data['destdir']));
+ }
+}
diff --git a/lib/functions/froxlor/function.inserttask.php b/lib/functions/froxlor/function.inserttask.php
index 41f7750b..3f2cdbde 100644
--- a/lib/functions/froxlor/function.inserttask.php
+++ b/lib/functions/froxlor/function.inserttask.php
@@ -101,5 +101,10 @@ function inserttask($type, $param1 = '', $param2 = '', $param3 = '', $param4 = '
$data = serialize($data);
Database::pexecute($ins_stmt, array('type' => '8', 'data' => $data));
+ } elseif ($type == '20'
+ && is_array($param1)
+ ) {
+ $data = serialize($param1);
+ Database::pexecute($ins_stmt, array('type' => '20', 'data' => $data));
}
}
diff --git a/lib/navigation/00.froxlor.main.php b/lib/navigation/00.froxlor.main.php
index eb7e7d21..cb6f0401 100644
--- a/lib/navigation/00.froxlor.main.php
+++ b/lib/navigation/00.froxlor.main.php
@@ -124,11 +124,15 @@ return array (
'url' => 'customer_extras.php?page=htaccess',
'label' => $lng['menue']['extras']['pathoptions'],
),
- array (
- 'url' => 'customer_logger.php?page=log',
- 'label' => $lng['menue']['logger']['logger'],
- 'show_element' => ( Settings::Get('logger.enabled') == true )
- ),
+ array (
+ 'url' => 'customer_logger.php?page=log',
+ 'label' => $lng['menue']['logger']['logger'],
+ 'show_element' => ( Settings::Get('logger.enabled') == true )
+ ),
+ array (
+ 'url' => 'customer_extras.php?page=backup',
+ 'label' => $lng['menue']['extras']['backup'],
+ ),
),
),
'traffic' => array (
diff --git a/lng/english.lng.php b/lng/english.lng.php
index 242ff7c5..8e0d72f0 100644
--- a/lng/english.lng.php
+++ b/lng/english.lng.php
@@ -1974,3 +1974,12 @@ $lng['domains']['termination_date_overview'] = 'canceled until ';
$lng['panel']['set'] = 'Apply';
$lng['customer']['selectserveralias_addinfo'] = 'This option can be set when editing the domain. Its initial value is inherited from the parent-domain.';
$lng['error']['mailaccistobedeleted'] = "Another account with the same name (%s) is currently being deleted and can therefore not be added at this moment.";
+
+$lng['menue']['extras']['backup'] = 'Backup';
+$lng['extras']['backup'] = 'Create backup';
+$lng['extras']['backup_web'] = 'Backup web-data';
+$lng['extras']['backup_mail'] = 'Backup mail-data';
+$lng['extras']['backup_dbs'] = 'Backup databases';
+$lng['error']['customerhasongoingbackupjob'] = 'There is already a backup job waiting to be processed, please be patient.';
+$lng['success']['backupscheduled'] = 'Your backup job has been scheduled. Please wait for it to be processed';
+$lng['crondesc']['cron_backup'] = 'Process backup jobs';
diff --git a/lng/german.lng.php b/lng/german.lng.php
index 38815cc9..6fe024b2 100644
--- a/lng/german.lng.php
+++ b/lng/german.lng.php
@@ -1627,3 +1627,12 @@ $lng['domains']['termination_date_overview'] = 'gekündigt zum ';
$lng['panel']['set'] = 'Setzen';
$lng['customer']['selectserveralias_addinfo'] = 'Diese Option steht beim Bearbeiten der Domain zur Verfügung. Als Initial-Wert wird die Einstellung der Hauptdomain vererbt.';
$lng['error']['mailaccistobedeleted'] = "Ein vorheriges Konto mit dem gleichen Namen (%s) wird aktuell noch gelöscht und kann daher derzeit nicht angelegt werden";
+
+$lng['menue']['extras']['backup'] = 'Sicherung';
+$lng['extras']['backup'] = 'Sicherung erstellen';
+$lng['extras']['backup_web'] = 'Web-Daten sichern';
+$lng['extras']['backup_mail'] = 'E-Mail Daten sichern';
+$lng['extras']['backup_dbs'] = 'Datenbanken sichern';
+$lng['error']['customerhasongoingbackupjob'] = 'Es gibt noch einen austehenden Backup-Job. Bitte haben Sie etwas Geduld.';
+$lng['success']['backupscheduled'] = 'Ihre Sicherung wurde erfolgreich geplant. Bitte warten Sie nun, bis diese abgearbeitet wurde.';
+$lng['crondesc']['cron_backup'] = 'Ausstehende Sicherungen erstellen';
diff --git a/scripts/jobs/cron_backup.php b/scripts/jobs/cron_backup.php
new file mode 100644
index 00000000..abecaca4
--- /dev/null
+++ b/scripts/jobs/cron_backup.php
@@ -0,0 +1,108 @@
+
+ * @author Froxlor team (2010-)
+ * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
+ * @package Cron
+ *
+ * @since 0.9.35.1
+ *
+ */
+
+// Check Traffic-Lock
+if (function_exists('pcntl_fork')) {
+ $BackupLock = makeCorrectFile(dirname($lockfile)."/froxlor_cron_backup.lock");
+ if (file_exists($BackupLock)
+ && is_numeric($BackupPid=file_get_contents($BackupLock))
+ ) {
+ if (function_exists('posix_kill')) {
+ $BackupPidStatus = @posix_kill($BackupPid,0);
+ } else {
+ system("kill -CHLD " . $BackupPid . " 1> /dev/null 2> /dev/null", $BackupPidStatus);
+ $BackupPidStatus = $BackupPidStatus ? false : true;
+ }
+ if ($BackupPidStatus) {
+ $cronlog->logAction(CRON_ACTION, LOG_INFO, 'Backup run already in progress');
+ return 1;
+ }
+ }
+ // Create Backup Log and Fork
+ // We close the database - connection before we fork, so we don't share resources with the child
+ Database::needRoot(false); // this forces the connection to be set to null
+ $BackupPid = pcntl_fork();
+ // Parent
+ if ($BackupPid) {
+ file_put_contents($BackupLock, $BackupPid);
+ // unnecessary to recreate database connection here
+ return 0;
+
+ }
+ //Child
+ elseif ($BackupPid == 0) {
+ posix_setsid();
+ fclose($debugHandler);
+ // re-create db
+ Database::needRoot(false);
+ }
+ //Fork failed
+ else {
+ return 1;
+ }
+
+} else {
+ if (extension_loaded('pcntl')) {
+ $msg = "PHP compiled with pcntl but pcntl_fork function is not available.";
+ } else {
+ $msg = "PHP compiled without pcntl.";
+ }
+ $cronlog->logAction(CRON_ACTION, LOG_WARNING, $msg." Not forking backup-cron, this may take a long time!");
+}
+
+$cronlog->logAction(CRON_ACTION, LOG_INFO, 'cron_backup: started - creating customer backup');
+
+$result_tasks_stmt = Database::query("
+ SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20' ORDER BY `id` ASC
+");
+
+$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `id` = :id");
+
+while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) {
+
+ if ($row['data'] != '') {
+ $row['data'] = unserialize($row['data']);
+ }
+
+ if (is_array($row['data'])) {
+
+ if (isset($row['data']['customerid'])
+ && isset($row['data']['loginname'])
+ && isset($row['data']['destdir'])
+ ) {
+ $row['data']['destdir'] = makeCorrectDir($row['data']['destdir']);
+ $customerdocroot = makeCorrectDir(Settings::Get('system.documentroot_prefix').'/'.$row['data']['loginname'].'/');
+
+ if (!file_exists($row['data']['destdir'])
+ && $row['data']['destdir'] != '/'
+ && $row['data']['destdir'] != Settings::Get('system.documentroot_prefix')
+ && $row['data']['destdir'] != $customerdocroot
+ ) {
+ $cronlog->logAction(CRON_ACTION, LOG_NOTICE, 'Creating backup-destination path for customer: ' . escapeshellarg($row['data']['destdir']));
+ safe_exec('mkdir -p '.escapeshellarg($row['data']['destdir']));
+ }
+
+ createCustomerBackup($row['data'], $customerdocroot, $cronlog);
+ }
+ }
+
+ // remove entry
+ Database::pexecute($del_stmt, array('id' => $row['id']));
+}
diff --git a/scripts/jobs/cron_tasks.php b/scripts/jobs/cron_tasks.php
index a614613b..b452c2d4 100644
--- a/scripts/jobs/cron_tasks.php
+++ b/scripts/jobs/cron_tasks.php
@@ -30,8 +30,9 @@ require_once makeCorrectFile(dirname(__FILE__) . '/cron_tasks.inc.http.35.nginx_
* LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS
*/
$cronlog->logAction(CRON_ACTION, LOG_INFO, "cron_tasks: Searching for tasks to do");
+// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
$result_tasks_stmt = Database::query("
- SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' ORDER BY `id` ASC
+ SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `id` ASC
");
$num_results = Database::num_rows();
$resultIDs = array();
@@ -395,7 +396,7 @@ while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) {
}
}
}
- }
+ }
}
}
}
diff --git a/templates/Sparkle/customer/extras/backup.tpl b/templates/Sparkle/customer/extras/backup.tpl
new file mode 100644
index 00000000..6e71243e
--- /dev/null
+++ b/templates/Sparkle/customer/extras/backup.tpl
@@ -0,0 +1,26 @@
+$header
+
+
+
+
+ {$title}
+
+
+
+
+
+
+$footer