mirror of
https://github.com/Froxlor/Froxlor.git
synced 2024-09-21 10:27:29 +00:00
Merge branch '2.1.x' of github.com:Froxlor/Froxlor into 2.1.x
This commit is contained in:
commit
a2fca3fe69
@ -38,7 +38,7 @@ use Froxlor\UI\Response;
|
||||
|
||||
$id = (int)Request::any('id');
|
||||
|
||||
if (($page == 'backups' || $page == 'overview') && $userinfo['change_serversettings'] == '1') {
|
||||
if (($page == 'backups' || $page == 'overview')) {
|
||||
if ($action == '') {
|
||||
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "viewed admin_backups");
|
||||
|
||||
@ -53,10 +53,6 @@ if (($page == 'backups' || $page == 'overview') && $userinfo['change_serversetti
|
||||
UI::view('user/table.html.twig', [
|
||||
'listing' => Listing::format($collection, $admin_list_data, 'backups_list'),
|
||||
'actions_links' => [
|
||||
[
|
||||
'href' => $linker->getLink(['section' => 'backups', 'page' => $page, 'action' => 'add']),
|
||||
'label' => lng('admin.backups_add')
|
||||
],
|
||||
[
|
||||
'href' => $linker->getLink(['section' => 'backups', 'page' => $page, 'action' => 'restore']),
|
||||
'label' => lng('admin.backups_restore'),
|
||||
@ -67,7 +63,8 @@ if (($page == 'backups' || $page == 'overview') && $userinfo['change_serversetti
|
||||
'href' => $linker->getLink(['section' => 'backups', 'page' => 'storages']),
|
||||
'label' => lng('admin.backup_storages'),
|
||||
'icon' => 'fa-solid fa-hard-drive',
|
||||
'class' => 'btn-outline-secondary'
|
||||
'class' => 'btn-outline-secondary',
|
||||
'visible' => $userinfo['change_serversettings'] == '1'
|
||||
]
|
||||
]
|
||||
]);
|
||||
@ -181,4 +178,6 @@ if (($page == 'backups' || $page == 'overview') && $userinfo['change_serversetti
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Response::dynamicError('403');
|
||||
}
|
||||
|
@ -63,24 +63,55 @@ class Backups extends ApiCommand implements ResourceEntity
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
$this->logger()->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] list backups");
|
||||
$query_fields = [];
|
||||
$result_stmt = Database::prepare("
|
||||
if ($this->isAdmin()) {
|
||||
// if we're an admin, list all backups of all the admins customers
|
||||
// or optionally for one specific customer identified by id or loginname
|
||||
$customerid = $this->getParam('customerid', true, 0);
|
||||
$loginname = $this->getParam('loginname', true, '');
|
||||
|
||||
if (!empty($customerid) || !empty($loginname)) {
|
||||
$result = $this->apiCall('Customers.get', [
|
||||
'id' => $customerid,
|
||||
'loginname' => $loginname
|
||||
]);
|
||||
$custom_list_result = [
|
||||
$result
|
||||
];
|
||||
} else {
|
||||
$_custom_list_result = $this->apiCall('Customers.listing');
|
||||
$custom_list_result = $_custom_list_result['list'];
|
||||
}
|
||||
$customer_ids = [];
|
||||
foreach ($custom_list_result as $customer) {
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
if (empty($customer_ids)) {
|
||||
throw new Exception("Required resource unsatisfied.", 405);
|
||||
}
|
||||
} else {
|
||||
$customer_ids = [
|
||||
$this->getUserDetail('customerid')
|
||||
];
|
||||
}
|
||||
|
||||
$this->logger()->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] list backups");
|
||||
$query_fields = [];
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `b`.*, `a`.`loginname` as `adminname`
|
||||
FROM `" . TABLE_PANEL_BACKUPS . "` `b`
|
||||
LEFT JOIN `" . TABLE_PANEL_ADMINS . "` `a` USING(`adminid`)
|
||||
WHERE `b`.`customerid` IN (" . implode(', ', $customer_ids) . ")
|
||||
");
|
||||
Database::pexecute($result_stmt, $query_fields, true, true);
|
||||
$result = [];
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
return $this->response([
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
]);
|
||||
Database::pexecute($result_stmt, $query_fields, true, true);
|
||||
$result = [];
|
||||
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row;
|
||||
}
|
||||
return $this->response([
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
]);
|
||||
|
||||
throw new Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
@ -93,7 +124,7 @@ class Backups extends ApiCommand implements ResourceEntity
|
||||
*/
|
||||
public function listingCount()
|
||||
{
|
||||
if ($this->isAdmin() && $this->getUserDetail('change_serversettings') == 1) {
|
||||
if ($this->isAdmin()) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT COUNT(*) as num_backups
|
||||
FROM `" . TABLE_PANEL_BACKUPS . "`
|
||||
|
@ -1059,17 +1059,19 @@ class SubDomains extends ApiCommand implements ResourceEntity
|
||||
$this->getUserDetail('customerid') => $this->getUserDetail('standardsubdomain')
|
||||
];
|
||||
}
|
||||
// prepare select statement
|
||||
$domains_stmt = Database::prepare("
|
||||
SELECT COUNT(*) as num_subdom
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
|
||||
WHERE `d`.`customerid` IN (" . implode(', ', $customer_ids) . ")
|
||||
AND `d`.`email_only` = '0'
|
||||
AND `d`.`id` NOT IN (" . implode(', ', $customer_stdsubs) . ")
|
||||
");
|
||||
$result = Database::pexecute_first($domains_stmt, null, true, true);
|
||||
if ($result) {
|
||||
return $this->response($result['num_subdom']);
|
||||
if (!empty($customer_ids)) {
|
||||
// prepare select statement
|
||||
$domains_stmt = Database::prepare("
|
||||
SELECT COUNT(*) as num_subdom
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
|
||||
WHERE `d`.`customerid` IN (" . implode(', ', $customer_ids) . ")
|
||||
AND `d`.`email_only` = '0'
|
||||
AND `d`.`id` NOT IN (" . implode(', ', $customer_stdsubs) . ")
|
||||
");
|
||||
$result = Database::pexecute_first($domains_stmt, null, true, true);
|
||||
if ($result) {
|
||||
return $this->response($result['num_subdom']);
|
||||
}
|
||||
}
|
||||
return $this->response(0);
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ namespace Froxlor\Cron\Backup;
|
||||
|
||||
use Froxlor\Cron\Forkable;
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use PDO;
|
||||
|
||||
class BackupCron extends FroxlorCron
|
||||
{
|
||||
@ -34,28 +38,45 @@ class BackupCron extends FroxlorCron
|
||||
|
||||
public static function run()
|
||||
{
|
||||
$users = ['web1', 'web2', 'web3', 'web4', 'web5', 'web6', 'web7', 'web8', 'web9', 'web10'];
|
||||
if(!Settings::Get('backup.enabled')) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'BackupCron: disabled - exiting');
|
||||
return -1;
|
||||
}
|
||||
|
||||
self::runFork([self::class, 'handle'], [
|
||||
[
|
||||
'user' => '1',
|
||||
'data' => 'value1',
|
||||
],
|
||||
[
|
||||
'user' => '2',
|
||||
'data' => 'value2',
|
||||
]
|
||||
]);
|
||||
$stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_BACKUP_STORAGES . "`");
|
||||
Database::pexecute($stmt);
|
||||
|
||||
$storages = [];
|
||||
while ($storage = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$storages[$storage['id']] = $storage;
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("SELECT
|
||||
customerid,
|
||||
loginname,
|
||||
adminid,
|
||||
backup,
|
||||
guid,
|
||||
documentroot
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `backup` > 0
|
||||
");
|
||||
Database::pexecute($stmt);
|
||||
|
||||
$customers = [];
|
||||
while ($customer = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$customer['storage'] = $storages[$customer['backup']];
|
||||
$customers[] = $customer;
|
||||
}
|
||||
|
||||
self::runFork([self::class, 'handle'], $customers);
|
||||
}
|
||||
|
||||
private static function handle(array $userdata)
|
||||
{
|
||||
echo "BackupCron: started - creating customer backup for user " . $userdata['user'] . "\n";
|
||||
echo "BackupCron: started - creating customer backup for user " . $userdata['loginname'] . "\n";
|
||||
|
||||
echo $userdata['data'] . "\n";
|
||||
echo json_encode($userdata['storage']) . "\n";
|
||||
|
||||
sleep(rand(1, 3));
|
||||
|
||||
echo "BackupCron: finished - creating customer backup for user " . $userdata['user'] . "\n";
|
||||
echo "BackupCron: finished - creating customer backup for user " . $userdata['loginname'] . "\n";
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +244,6 @@ return [
|
||||
],
|
||||
'server' => [
|
||||
'label' => lng('admin.server'),
|
||||
'required_resources' => 'change_serversettings',
|
||||
'icon' => 'fa-solid fa-server',
|
||||
'elements' => [
|
||||
[
|
||||
@ -265,14 +264,11 @@ return [
|
||||
[
|
||||
'url' => 'admin_backups.php?page=overview',
|
||||
'label' => lng('admin.backups.backups'),
|
||||
'required_resources' => 'change_serversettings',
|
||||
'add_shortlink' => 'admin_backups.php?page=overview&action=add',
|
||||
'show_element' => (Settings::Get('backup.enabled') == true)
|
||||
],
|
||||
[
|
||||
'url' => 'admin_logger.php?page=log',
|
||||
'label' => lng('menue.logger.logger'),
|
||||
'required_resources' => 'change_serversettings',
|
||||
'show_element' => (Settings::Get('logger.enabled') == true)
|
||||
],
|
||||
[
|
||||
|
@ -84,7 +84,7 @@ return [
|
||||
'sortable' => true,
|
||||
],
|
||||
],
|
||||
'visible_columns' => Listing::getVisibleColumnsForListing('admin_list', [
|
||||
'visible_columns' => Listing::getVisibleColumnsForListing('backup_storages_list', [
|
||||
'id',
|
||||
'description',
|
||||
'type',
|
||||
@ -94,8 +94,6 @@ return [
|
||||
'show' => [
|
||||
'icon' => 'fa-solid fa-eye',
|
||||
'title' => lng('usersettings.custom_notes.title'),
|
||||
'modal' => [Text::class, 'customerNoteDetailModal'],
|
||||
'visible' => [Customer::class, 'hasNote']
|
||||
],
|
||||
'edit' => [
|
||||
'icon' => 'fa-solid fa-edit',
|
||||
@ -117,13 +115,7 @@ return [
|
||||
'action' => 'delete',
|
||||
'id' => ':id'
|
||||
],
|
||||
'visible' => [Admin::class, 'isNotMe']
|
||||
],
|
||||
],
|
||||
'format_callback' => [
|
||||
[Style::class, 'deactivated'],
|
||||
[Style::class, 'diskspaceWarning'],
|
||||
[Style::class, 'trafficWarning']
|
||||
]
|
||||
]
|
||||
];
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
use Froxlor\UI\Callbacks\Admin;
|
||||
use Froxlor\UI\Callbacks\Backup;
|
||||
use Froxlor\UI\Callbacks\Customer;
|
||||
use Froxlor\UI\Callbacks\Impersonate;
|
||||
use Froxlor\UI\Callbacks\ProgressBar;
|
||||
@ -63,20 +64,32 @@ return [
|
||||
'label' => lng('admin.admin'),
|
||||
'field' => 'adminname',
|
||||
'callback' => [Impersonate::class, 'admin'],
|
||||
'sortable' => true,
|
||||
],
|
||||
'size' => [
|
||||
'label' => lng('backup.size'),
|
||||
'field' => 'size',
|
||||
'sortable' => true,
|
||||
'callback' => [Text::class, 'size'],
|
||||
],
|
||||
'storage_id' => [
|
||||
'label' => lng('backup.backup_storage.title'),
|
||||
'field' => 'storage_id',
|
||||
'class' => 'text-center',
|
||||
'callback' => [Backup::class, 'backupStorageLink'],
|
||||
],
|
||||
'filename' => [
|
||||
'label' => lng('backup.size'),
|
||||
'field' => 'filename',
|
||||
'sortable' => true,
|
||||
],
|
||||
'created_at' => [
|
||||
'label' => lng('backup.created_at'),
|
||||
'field' => 'created_at',
|
||||
'sortable' => true,
|
||||
'callback' => [Text::class, 'timestamp'],
|
||||
],
|
||||
],
|
||||
'visible_columns' => Listing::getVisibleColumnsForListing('admin_list', [
|
||||
'visible_columns' => Listing::getVisibleColumnsForListing('backups_list', [
|
||||
'id',
|
||||
'adminname',
|
||||
'loginname',
|
||||
@ -84,22 +97,6 @@ return [
|
||||
'created_at',
|
||||
]),
|
||||
'actions' => [
|
||||
'show' => [
|
||||
'icon' => 'fa-solid fa-eye',
|
||||
'title' => lng('usersettings.custom_notes.title'),
|
||||
'modal' => [Text::class, 'customerNoteDetailModal'],
|
||||
'visible' => [Customer::class, 'hasNote']
|
||||
],
|
||||
'edit' => [
|
||||
'icon' => 'fa-solid fa-edit',
|
||||
'title' => lng('panel.edit'),
|
||||
'href' => [
|
||||
'section' => 'backups',
|
||||
'page' => 'storages',
|
||||
'action' => 'edit',
|
||||
'id' => ':id'
|
||||
],
|
||||
],
|
||||
'delete' => [
|
||||
'icon' => 'fa-solid fa-trash',
|
||||
'title' => lng('panel.delete'),
|
||||
@ -110,13 +107,8 @@ return [
|
||||
'action' => 'delete',
|
||||
'id' => ':id'
|
||||
],
|
||||
'visible' => [Admin::class, 'isNotMe']
|
||||
'visible' => [Admin::class, 'canChangeServerSettings'],
|
||||
],
|
||||
],
|
||||
'format_callback' => [
|
||||
[Style::class, 'deactivated'],
|
||||
[Style::class, 'diskspaceWarning'],
|
||||
[Style::class, 'trafficWarning']
|
||||
]
|
||||
]
|
||||
];
|
||||
|
@ -31,18 +31,13 @@
|
||||
<div>
|
||||
{% if actions_links is iterable %}
|
||||
{% for link in actions_links %}
|
||||
<a class="btn {{ link.class|default('btn-outline-primary') }}" href="{{ link.href|raw }}">
|
||||
<i class="{{ link.icon|default('fa-solid fa-plus-circle') }}"></i><span class="d-none d-lg-inline ms-lg-1">{{ link.label }}</span>
|
||||
</a>
|
||||
{% if link.visible is not defined or (link.visible is defined and link.visible == true) %}
|
||||
<a class="btn {{ link.class|default('btn-outline-primary') }}" href="{{ link.href|raw }}">
|
||||
<i class="{{ link.icon|default('fa-solid fa-plus-circle') }}"></i><span class="d-none d-lg-inline ms-lg-1">{{ link.label }}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{# TODO: eventually not used anymore because of using a documentation link
|
||||
{% if entity_info is defined and entity_info is not empty %}
|
||||
<div class="alert alert-info" role="alert">
|
||||
{{ entity_info|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
#}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
@ -33,19 +33,14 @@
|
||||
<div>
|
||||
{% if actions_links is iterable %}
|
||||
{% for link in actions_links %}
|
||||
<a class="btn {{ link.class|default('btn-outline-primary') }}" href="{{ link.href|raw }}">
|
||||
<i class="{{ link.icon|default('fa-solid fa-plus-circle') }}"></i>
|
||||
{% if link.label is defined and link.label is not empty %}<span class="d-none d-lg-inline ms-lg-1">{{ link.label }}</span>{% endif %}
|
||||
</a>
|
||||
{% if link.visible is not defined or (link.visible is defined and link.visible == true) %}
|
||||
<a class="btn {{ link.class|default('btn-outline-primary') }}" href="{{ link.href|raw }}">
|
||||
<i class="{{ link.icon|default('fa-solid fa-plus-circle') }}"></i>
|
||||
{% if link.label is defined and link.label is not empty %}<span class="d-none d-lg-inline ms-lg-1">{{ link.label }}</span>{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{# TODO: eventually not used anymore because of using a documentation link
|
||||
{% if entity_info is defined and entity_info is not empty %}
|
||||
<div class="alert alert-info" role="alert">
|
||||
{{ entity_info|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
#}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user