diff --git a/app/Web/Routes/admin/backups.php b/app/Web/Routes/admin/backups.php new file mode 100644 index 0000000..83c7204 --- /dev/null +++ b/app/Web/Routes/admin/backups.php @@ -0,0 +1,105 @@ +add('/admin/backups', function (): void { + global $router, $event, $renderer; + $template = 'admin/backups/list.twig'; + if (isset($_COOKIE['token']) === false) { + exit(header('location: /auth/login')); + } + + $user = new UserHelper($_COOKIE['token'], $renderer); + UserDataHandler::requireAuthorization($renderer, $_COOKIE['token']); + $uuid = UserDataHandler::getSpecificUserData($_COOKIE['token'], 'uuid', false); + + + if ( + !UserDataHandler::hasPermission($_COOKIE['token'], "mythicalframework.admin.backups.view") || + !UserDataHandler::hasPermission($_COOKIE['token'], "mythicalframework.admin.backups.create") || + !UserDataHandler::hasPermission($_COOKIE['token'], "mythicalframework.admin.backups.delete") + ) { + exit(header('location: /errors/403')); + } + + $backups = Backup::getBackups(); + $renderer->addGlobal('backups', $backups); + $renderer->addGlobal('page_name', 'Backups'); + + Engine::registerAlerts($renderer, $template); + exit($renderer->render($template)); +}); + +$router->add('/admin/backups/(.*)/restore', function ($id): void { + global $router, $event, $renderer; + if (isset($_COOKIE['token']) === false) { + exit(header('location: /auth/login')); + } + + $user = new UserHelper($_COOKIE['token'], $renderer); + UserDataHandler::requireAuthorization($renderer, $_COOKIE['token']); + + if ( + !UserDataHandler::hasPermission($_COOKIE['token'], "mythicalframework.admin.backups.restore") + ) { + exit(header('location: /errors/403')); + } + + if (Backup::doesBackupExist($id) == false) { + exit(header('location: /admin/backups?s=not_found')); + } else { + Backup::restore($id); + exit(header('location: /admin/backups?s=ok')); + } +}); + +$router->add('/admin/backups/(.*)/delete', function ($id): void { + global $router, $event, $renderer; + if (isset($_COOKIE['token']) === false) { + exit(header('location: /auth/login')); + } + + $user = new UserHelper($_COOKIE['token'], $renderer); + UserDataHandler::requireAuthorization($renderer, $_COOKIE['token']); + + if ( + !UserDataHandler::hasPermission($_COOKIE['token'], "mythicalframework.admin.backups.delete") + ) { + exit(header('location: /errors/403')); + } + if (Backup::doesBackupExist($id) == false) { + exit(header('location: /admin/backups?s=not_found')); + } else { + Backup::remove($id); + exit(header('location: /admin/backups?s=ok')); + } + + +}); + +$router->add('/admin/backups/create', function (): void { + global $router, $event, $renderer; + if (isset($_COOKIE['token']) === false) { + exit(header('location: /auth/login')); + } + + $user = new UserHelper($_COOKIE['token'], $renderer); + UserDataHandler::requireAuthorization($renderer, $_COOKIE['token']); + + if ( + !UserDataHandler::hasPermission($_COOKIE['token'], "mythicalframework.admin.backups.create") + ) { + exit(header('location: /errors/403')); + } + + $backup = Backup::take(); + Backup::setBackupStatus($backup, \MythicalSystemsFramework\Backup\Status::DONE); + + exit(header('location: /admin/backups?s=ok')); +}); \ No newline at end of file diff --git a/public/assets/MythicalFramework.js b/public/assets/MythicalFramework.js index 026a35e..d36729b 100755 --- a/public/assets/MythicalFramework.js +++ b/public/assets/MythicalFramework.js @@ -305,4 +305,27 @@ function showDialogWithInput(title, text, confirmButtonText, cancelButtonText) { return ""; } }); -} \ No newline at end of file +} + +/** + * Highlight active sidebar menu item based on current URL + */ +document.addEventListener('DOMContentLoaded', function () { + const currentUrl = window.location.pathname; + const menuItems = document.querySelectorAll('#layout-menu .menu-item a'); + + menuItems.forEach((menuItem) => { + const menuItemUrl = menuItem.getAttribute('href'); + if (menuItemUrl === currentUrl) { + menuItem.classList.add('active'); + const parentMenuItem = menuItem.closest('.menu-item'); + if (parentMenuItem) { + parentMenuItem.classList.add('active'); + const parentMenuToggle = parentMenuItem.querySelector('.menu-toggle'); + if (parentMenuToggle) { + parentMenuToggle.classList.add('active'); + } + } + } + }); +}); \ No newline at end of file diff --git a/storage/addons/Core/permissions.json b/storage/addons/Core/permissions.json index 091eea0..4dc3c0e 100755 --- a/storage/addons/Core/permissions.json +++ b/storage/addons/Core/permissions.json @@ -26,6 +26,7 @@ "mythicalframework.admin.backups.view", "mythicalframework.admin.backups.create", + "mythicalframework.admin.backups.restore", "mythicalframework.admin.backups.delete", "mythicalframework.admin.logs.view", diff --git a/storage/lang/en_US.yml b/storage/lang/en_US.yml index 3817dce..d8b21ef 100755 --- a/storage/lang/en_US.yml +++ b/storage/lang/en_US.yml @@ -21,7 +21,22 @@ Pages: AdminArea: - Pages: + Pages: + Backups: + List: + Title: "Backups" + Description: "Here you can manage all the backups." + Table: + CreateButton: "Create new backup" + Head: + Columns: + ID: "ID" + Status: "Status" + Date: "Date" + Actions: "Actions" + Actions: + Restore: "Restore" + Delete: "Delete" Announcements: Create: Title: "Create Announcement" diff --git a/storage/themes/v2/admin/backups/list.twig b/storage/themes/v2/admin/backups/list.twig new file mode 100644 index 0000000..1f3a5b2 --- /dev/null +++ b/storage/themes/v2/admin/backups/list.twig @@ -0,0 +1,46 @@ +{% extends 'components/dashboard.twig' %} + +{% block head %}{% endblock %} + +{% block dashboard %} +
+
+
+

{{ lang('Pages.AdminArea.Pages.Backups.List.Title') }}

+

{{ lang('Pages.AdminArea.Pages.Backups.List.Description') }}

+
+ +
+ + + + + + + + + + + {% for backup in backups %} + + + + + + + {% endfor %} + +
{{lang('Pages.AdminArea.Pages.Backups.List.Table.Head.Columns.ID')}}{{lang('Pages.AdminArea.Pages.Backups.List.Table.Head.Columns.Status') }}{{lang('Pages.AdminArea.Pages.Backups.List.Table.Head.Columns.Date')}}{{lang('Pages.AdminArea.Pages.Backups.List.Table.Head.Columns.Actions')}}
{{ backup.id }}{{ backup.backup_status }}{{ backup.backup_date_end }} + + +
+
+
+ +{% endblock %}{% block footer %} +{% include 'requirements/datatables.twig' %} + {% endblock %} diff --git a/storage/themes/v2/components/sidebar.twig b/storage/themes/v2/components/sidebar.twig index ade1c19..874fd26 100755 --- a/storage/themes/v2/components/sidebar.twig +++ b/storage/themes/v2/components/sidebar.twig @@ -39,7 +39,7 @@ {% if hasPermission("mythicalframework.admin.ticket.view") or hasPermission("mythicalframework.admin.ticket.create") or hasPermission("mythicalframework.admin.ticket.reply") or hasPermission("mythicalframework.admin.ticket.delete") %} {% endif %} - {% if hasPermission("mythicalframework.admin.backups.view") or hasPermission("mythicalframework.admin.backups.create") or hasPermission("mythicalframework.admin.backups.delete") %} + {% if hasPermission("mythicalframework.admin.backups.view") or hasPermission("mythicalframework.admin.backups.restore") or hasPermission("mythicalframework.admin.backups.create") or hasPermission("mythicalframework.admin.backups.delete") %}