diff --git a/.editorconfig b/.editorconfig index 042d009..6537ca4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,15 +1,15 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - root = true [*] -end_of_line = lf charset = utf-8 +end_of_line = lf +insert_final_newline = true indent_style = space indent_size = 4 trim_trailing_whitespace = true -insert_final_newline = true [*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] indent_size = 2 diff --git a/.gitattributes b/.gitattributes index c8d6ba3..2b7b41d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,13 @@ -/_docs export-ignore -/tests export-ignore -/.editorconfig export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore -/.scrutinizer.yml export-ignore -/.travis.yml export-ignore -/CONTRIBUTING.md export-ignore -/phpunit.xml.dist export-ignore +* text=auto + +/.github export-ignore +/_docs export-ignore +/tests export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.scrutinizer.yml export-ignore +.travis.yml export-ignore +phpcs.xml.dist export-ignore +phpunit.xml.dist export-ignore +CONTRIBUTING.md export-ignore diff --git a/.gitignore b/.gitignore index 697e972..8c59329 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /build/ /vendor/ -composer.lock -composer.phar +/composer.phar +/composer.lock diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 03a87c5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: php - -sudo: false - -php: - - 7.0 - - 7.1 - - nightly - -matrix: - allow_failures: - - php: nightly - -env: - - TESTBENCH_VERSION=3.5.* - -before_script: - - travis_retry composer self-update - - travis_retry composer require --prefer-source --no-interaction --dev "orchestra/testbench:${TESTBENCH_VERSION}" - -script: - - composer validate - - mkdir -p build/logs - - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - -after_script: - - if [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi - - if [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi diff --git a/LICENSE.md b/LICENSE.md index 8ec448c..6e66795 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017 | ARCANEDEV - Backups +Copyright (c) 2017-2020 | ARCANEDEV - Backups Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json index 6140c17..3f7b8fd 100644 --- a/composer.json +++ b/composer.json @@ -14,14 +14,13 @@ "type": "library", "license": "MIT", "require": { - "php": ">=7.0", - "arcanesoft/auth": "~3.0", - "arcanesoft/core": "~2.6", - "spatie/laravel-backup": "~5.0" + "php": "^7.3|^8.0", + "arcanedev/laravel-backup": "^3.2", + "arcanesoft/foundation": "^4.0" }, "require-dev": { - "phpunit/phpunit": "~6.0", - "phpunit/phpcov": "~4.0" + "orchestra/testbench-core": "^6.0", + "phpunit/phpunit": "^9.3" }, "autoload": { "psr-4": { @@ -34,6 +33,26 @@ } }, "scripts": { - "testbench": "composer require --dev \"orchestra/testbench=~3.5.0\"" - } + "test": "phpunit", + "test:dox": "phpunit --testdox" + }, + "extra": { + "branch-alias": { + "dev-develop": "4.x-dev" + }, + "laravel": { + "providers": [ + "Arcanesoft\\Backups\\BackupsServiceProvider" + ] + }, + "arcanesoft": { + "install": "Arcanesoft\\Backups\\Console\\InstallCommand", + "publish": "Arcanesoft\\Backups\\Console\\PublishCommand" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/config/backups.php b/config/backups.php deleted file mode 100644 index 154350a..0000000 --- a/config/backups.php +++ /dev/null @@ -1,14 +0,0 @@ - [ - 'prefix' => 'backups', - ], - -]; diff --git a/config/policies.php b/config/policies.php new file mode 100644 index 0000000..96336c8 --- /dev/null +++ b/config/policies.php @@ -0,0 +1,12 @@ + [ + [ + 'name' => 'foundation::backups', + 'title' => 'Backups', + 'icon' => 'fas fa-fw fa-database', + 'route' => 'admin::backups.statuses.index', + 'roles' => [], + 'permissions' => [ + 'admin::backups.statuses.index', + ], + ], + ], + +]; diff --git a/config/sidebar/main.php b/config/sidebar/main.php deleted file mode 100644 index 55a974e..0000000 --- a/config/sidebar/main.php +++ /dev/null @@ -1,18 +0,0 @@ - 'backups::sidebar.backups', - 'name' => 'backups-statuses', - 'route' => 'admin::backups.statuses.index', - 'icon' => 'fa fa-fw fa-database', - 'roles' => [Role::ADMINISTRATOR], - 'permissions' => [ - StatusesPolicy::PERMISSION_LIST, - ], - 'children' => [ - // - ], -]; diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9cc7cf2..b08327f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,28 +1,22 @@ - - ./tests/ + ./tests/ - - - ./src/ - - - - - - - + + + ./src + + + + + + + diff --git a/resources/lang/en/sidebar.php b/resources/lang/en/sidebar.php deleted file mode 100644 index cfbf178..0000000 --- a/resources/lang/en/sidebar.php +++ /dev/null @@ -1,7 +0,0 @@ - 'Backups', - -]; diff --git a/resources/lang/en/statuses.php b/resources/lang/en/statuses.php deleted file mode 100644 index 07bbc40..0000000 --- a/resources/lang/en/statuses.php +++ /dev/null @@ -1,79 +0,0 @@ - [ - 'name' => 'Name', - 'disk' => 'Disk', - 'reachable' => 'Reachable', - 'healthy' => 'Healthy', - 'number_of_backups' => '# of backups', - 'newest_backup' => 'Newest backup', - 'used_storage' => 'Used storage', - - 'date' => 'Date', - 'path' => 'Path', - 'size' => 'Size', - ], - - /* ----------------------------------------------------------------- - | Titles - | ----------------------------------------------------------------- - */ - - 'titles' => [ - 'backups' => 'Backups', - 'monitor-status' => 'Monitor Status', - 'monitor-statuses-list' => 'List of Monitor Statuses', - ], - - /* ----------------------------------------------------------------- - | Actions - | ----------------------------------------------------------------- - */ - - 'actions' => [ - 'run-backups' => 'Run Backups', - 'clear-backups' => 'Clear Backups', - ], - - /* ----------------------------------------------------------------- - | Messages - | ----------------------------------------------------------------- - */ - - 'messages' => [ - 'created' => [ - 'title' => 'Backups created !', - 'message' => 'The Backups was created successfully !', - ], - - 'cleared' => [ - 'title' => 'Backups cleared !', - 'message' => 'The Backups was cleared successfully !', - ], - ], - - /* ----------------------------------------------------------------- - | Modals - | ----------------------------------------------------------------- - */ - - 'modals' => [ - 'backup' => [ - 'title' => 'Backup all', - 'message' => 'Are you sure you want to run the backups ?', - ], - - 'clear' => [ - 'title' => 'Clear all backups', - 'message' => 'Are you sure you want to clear all the backups ?', - ], - ], - -]; diff --git a/resources/lang/fr/sidebar.php b/resources/lang/fr/sidebar.php deleted file mode 100644 index 0b1f166..0000000 --- a/resources/lang/fr/sidebar.php +++ /dev/null @@ -1,7 +0,0 @@ - 'Sauvegardes', - -]; diff --git a/resources/lang/fr/statuses.php b/resources/lang/fr/statuses.php deleted file mode 100644 index 24cb7f0..0000000 --- a/resources/lang/fr/statuses.php +++ /dev/null @@ -1,79 +0,0 @@ - [ - 'name' => 'Nom', - 'disk' => 'Disque', - 'reachable' => 'Accessible', - 'healthy' => 'Sain', - 'number_of_backups' => 'Nbr de sauvegardes', - 'newest_backup' => 'La plus récente sauvegarde', - 'used_storage' => 'Stockage utilisé', - - 'date' => 'Date', - 'path' => 'Chemin', - 'size' => 'Taille', - ], - - /* ----------------------------------------------------------------- - | Titles - | ----------------------------------------------------------------- - */ - - 'titles' => [ - 'backups' => 'Sauvegardes', - 'monitor-status' => 'Statut du moniteur', - 'monitor-statuses-list' => 'Liste des statuts du moniteur', - ], - - /* ----------------------------------------------------------------- - | Actions - | ----------------------------------------------------------------- - */ - - 'actions' => [ - 'run-backups' => 'Exécuter les sauvegardes', - 'clear-backups' => 'Nettoyer les sauvegardes', - ], - - /* ----------------------------------------------------------------- - | Messages - | ----------------------------------------------------------------- - */ - - 'messages' => [ - 'created' => [ - 'title' => 'Sauvegardes créées !', - 'message' => 'Les sauvegardes ont été créées avec succès !', - ], - - 'cleared' => [ - 'title' => 'Sauvegardes effacées !', - 'message' => 'Les sauvegardes ont été effacées avec succès!', - ], - ], - - /* ----------------------------------------------------------------- - | Modals - | ----------------------------------------------------------------- - */ - - 'modals' => [ - 'backup' => [ - 'title' => 'Sauvegarder tout', - 'message' => 'Êtes-vous sûr de vouloir exécuter la sauvegarde des base de données ?', - ], - - 'clear' => [ - 'title' => 'Effacer toutes les sauvegardes', - 'message' => 'Êtes-vous sûr de vouloir nettoyer toutes les anciennes sauvegardes ?', - ], - ], - -]; diff --git a/resources/views/admin/statuses/index.blade.php b/resources/views/admin/statuses/index.blade.php deleted file mode 100644 index dd5de60..0000000 --- a/resources/views/admin/statuses/index.blade.php +++ /dev/null @@ -1,223 +0,0 @@ -@section('header') -

{{ trans('backups::statuses.titles.backups') }} {{ trans('backups::statuses.titles.monitor-statuses-list') }}

-@endsection - -@section('content') -
-
-

{{ trans('backups::statuses.titles.monitor-statuses-list') }}

-
- @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_CREATE) - - {{ trans('backups::statuses.actions.run-backups') }} - - @endcan - - @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_DELETE) - - {{ trans('backups::statuses.actions.clear-backups') }} - - @endcan -
-
-
-
- - - - - - - - - - - - - - - @forelse($statuses as $index => $status) - - - - - - - - - - - @empty - @endforelse - -
{{ trans('backups::statuses.attributes.disk') }}{{ trans('backups::statuses.attributes.name') }}{{ trans('backups::statuses.attributes.reachable') }}{{ trans('backups::statuses.attributes.healthy') }}{{ trans('backups::statuses.attributes.number_of_backups') }}{{ trans('backups::statuses.attributes.newest_backup') }}{{ trans('backups::statuses.attributes.used_storage') }}{{ trans('core::generals.actions') }}
- {{ $status->diskName() }} - - {{ $status->backupName() }} - - @if ($status->isReachable()) - Yes - @else - No - @endif - - @if ($status->isHealthy()) - Yes - @else - No - @endif - - @if ($status->isReachable()) - {{ label_count($status->amountOfBackups()) }} - @else - / - @endif - - @if ($status->isReachable()) - {{ $status->dateOfNewestBackup() ?: 'No backups present' }} - @else - / - @endif - - @if ($status->isReachable()) - {{ $status->humanReadableUsedStorage() }} - @else - / - @endif - - @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_SHOW) - {{ ui_link_icon('show', route('admin::backups.statuses.show', [$index])) }} - @endcan -
-
-
-
-@endsection - -@section('modals') - @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_CREATE) - - @endcan - - @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_DELETE) - - @endcan -@endsection - -@section('scripts') - {{-- RUN BACKUPS MODAL --}} - @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_CREATE) - - @endcan - - {{-- CLEAR BACKUPS MODAL --}} - @can(Arcanesoft\Backups\Policies\StatusesPolicy::PERMISSION_DELETE) - - @endcan -@endsection diff --git a/resources/views/admin/statuses/show.blade.php b/resources/views/admin/statuses/show.blade.php deleted file mode 100644 index 77e22cb..0000000 --- a/resources/views/admin/statuses/show.blade.php +++ /dev/null @@ -1,130 +0,0 @@ -@section('header') -

{{ trans('backups::statuses.titles.backups') }} {{ trans('backups::statuses.titles.monitor-status') }}

-@endsection - -@section('content') -
-
-
-
-

{{ trans('backups::statuses.titles.monitor-status') }}

-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{ trans('backups::statuses.attributes.name') }} : - {{ $status->backupName() }} -
{{ trans('backups::statuses.attributes.disk') }} : - {{ $status->diskName() }} -
{{ trans('backups::statuses.attributes.reachable') }} : - @if ($status->isReachable()) - Yes - @else - No - @endif -
{{ trans('backups::statuses.attributes.healthy') }} : - @if ($status->isHealthy()) - Yes - @else - No - @endif -
{{ trans('backups::statuses.attributes.number_of_backups') }} : - @if ($status->isReachable()) - {{ label_count($status->amountOfBackups()) }} - @else - / - @endif -
{{ trans('backups::statuses.attributes.newest_backup') }} : - @if ($status->isReachable()) - {{ $status->dateOfNewestBackup() ?: 'null' }} - @else - / - @endif -
{{ trans('backups::statuses.attributes.used_storage') }} : - @if ($status->isReachable()) - {{ $status->humanReadableUsedStorage() }} - @else - / - @endif -
-
-
-
-
- -
-
-
-

{{ trans('backups::statuses.titles.backups') }}

-
-
-
- - - - - - - - - - @forelse ($backups as $backup) - - - - - - @empty - - - - @endforelse - -
{{ trans('backups::statuses.attributes.date') }}{{ trans('backups::statuses.attributes.path') }}{{ trans('backups::statuses.attributes.size') }}
- {{ $backup->date() }} - - {{ $backup->path() }} - - - {{ Spatie\Backup\Helpers\Format::humanReadableSize($backup->size()) }} - -
- There is no backups for the time being -
-
-
-
-
-
-@endsection - -@section('scripts') -@endsection diff --git a/src/BackupsServiceProvider.php b/src/BackupsServiceProvider.php index 9fcab48..df10bf4 100644 --- a/src/BackupsServiceProvider.php +++ b/src/BackupsServiceProvider.php @@ -1,11 +1,15 @@ - */ class BackupsServiceProvider extends PackageServiceProvider @@ -22,6 +26,13 @@ class BackupsServiceProvider extends PackageServiceProvider */ protected $package = 'backups'; + /** + * Merge multiple config files into one instance (package name as root key) + * + * @var bool + */ + protected $multiConfigs = true; + /* ----------------------------------------------------------------- | Main Methods | ----------------------------------------------------------------- @@ -30,44 +41,32 @@ class BackupsServiceProvider extends PackageServiceProvider /** * Register the service provider. */ - public function register() + public function register(): void { - parent::register(); - $this->registerConfig(); - $this->registerSidebarItems(); $this->registerProviders([ - Providers\PackagesServiceProvider::class, - Providers\AuthorizationServiceProvider::class, + Providers\AuthServiceProvider::class, Providers\RouteServiceProvider::class, ]); - $this->registerConsoleServiceProvider(Providers\CommandServiceProvider::class); + + $this->registerCommands([ + PublishCommand::class, + ]); } /** * Boot the service provider. */ - public function boot() + public function boot(): void { - parent::boot(); - - // Publishes - $this->publishConfig(); - $this->publishViews(); - $this->publishTranslations(); - $this->publishSidebarItems(); - } + $this->loadTranslations(); + $this->loadViews(); - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { - return [ - // - ]; + if ($this->app->runningInConsole()) { + $this->publishConfig(); + $this->publishTranslations(); + $this->publishViews(); + } } } diff --git a/src/Console/InstallCommand.php b/src/Console/InstallCommand.php index 35aad9b..ef80cd6 100644 --- a/src/Console/InstallCommand.php +++ b/src/Console/InstallCommand.php @@ -1,12 +1,15 @@ - */ class InstallCommand extends Command @@ -21,7 +24,7 @@ class InstallCommand extends Command * * @var string */ - protected $signature = 'backups:install'; + protected $signature = 'backups:install'; /** * The console command description. @@ -38,8 +41,8 @@ class InstallCommand extends Command /** * Execute the console command. */ - public function handle() + public function handle(): void { - $this->call('db:seed', ['--class' => DatabaseSeeder::class]); + $this->seed(DatabaseSeeder::class); } } diff --git a/src/Console/PublishCommand.php b/src/Console/PublishCommand.php index 2ea8923..3f1e6d6 100644 --- a/src/Console/PublishCommand.php +++ b/src/Console/PublishCommand.php @@ -1,12 +1,15 @@ - */ class PublishCommand extends Command diff --git a/src/Database/DatabaseSeeder.php b/src/Database/DatabaseSeeder.php new file mode 100644 index 0000000..f9e9813 --- /dev/null +++ b/src/Database/DatabaseSeeder.php @@ -0,0 +1,34 @@ + + */ +class DatabaseSeeder extends Seeder +{ + /* ----------------------------------------------------------------- + | Main Methods + | ----------------------------------------------------------------- + */ + + /** + * Get the seeders. + * + * @return array + */ + public function seeders(): array + { + return [ + PermissionsSeeder::class, + RolesSeeder::class, + ]; + } +} diff --git a/src/Database/Seeders/PermissionsSeeder.php b/src/Database/Seeders/PermissionsSeeder.php new file mode 100644 index 0000000..789abb7 --- /dev/null +++ b/src/Database/Seeders/PermissionsSeeder.php @@ -0,0 +1,32 @@ + + */ +class PermissionsSeeder extends Seeder +{ + /* ----------------------------------------------------------------- + | Main Methods + | ----------------------------------------------------------------- + */ + + /** + * Run the database seeds. + */ + public function run(): void + { + $this->seed([ + 'name' => 'Backups', + 'slug' => 'backups', + 'description' => 'backups permissions group', + ], $this->getPermissionsFromPolicyManager('admin::backups.')); + } +} diff --git a/src/Seeds/RolesTableSeeder.php b/src/Database/Seeders/RolesSeeder.php similarity index 56% rename from src/Seeds/RolesTableSeeder.php rename to src/Database/Seeders/RolesSeeder.php index f434437..752a98c 100644 --- a/src/Seeds/RolesTableSeeder.php +++ b/src/Database/Seeders/RolesSeeder.php @@ -1,14 +1,17 @@ - */ -class RolesTableSeeder extends RolesSeeder +class RolesSeeder extends Seeder { /* ----------------------------------------------------------------- | Main Methods @@ -18,9 +21,9 @@ class RolesTableSeeder extends RolesSeeder /** * Run the database seeds. */ - public function run() + public function run(): void { - $this->seed([ + $this->seedMany([ [ 'name' => 'Backups Manager', 'description' => 'The Backups manager role.', @@ -28,9 +31,10 @@ public function run() ], ]); - $this->syncAdminRole(); - $this->syncRoles([ - 'backups-manager' => 'backups.', + $this->syncRolesWithPermissions([ + 'backups-manager' => [ + 'admin::backups.*', + ], ]); } } diff --git a/src/Http/Controllers/Admin/Controller.php b/src/Http/Controllers/Admin/Controller.php deleted file mode 100644 index ba57ea7..0000000 --- a/src/Http/Controllers/Admin/Controller.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ -abstract class Controller extends AdminController -{ - /* ----------------------------------------------------------------- - | Traits - | ----------------------------------------------------------------- - */ - - use Notifyable; - - /* ----------------------------------------------------------------- - | Properties - | ----------------------------------------------------------------- - */ - - /** - * The view namespace. - * - * @var string - */ - protected $viewNamespace = 'backups'; -} diff --git a/src/Http/Controllers/Controller.php b/src/Http/Controllers/Controller.php new file mode 100644 index 0000000..9bb6613 --- /dev/null +++ b/src/Http/Controllers/Controller.php @@ -0,0 +1,27 @@ + + */ +abstract class Controller extends BaseController +{ + /* ----------------------------------------------------------------- + | Properties + | ----------------------------------------------------------------- + */ + + /** + * The view namespace. + * + * @var string + */ + protected $viewNamespace = 'backups'; +} diff --git a/src/Http/Controllers/Admin/StatusesController.php b/src/Http/Controllers/StatusesController.php similarity index 51% rename from src/Http/Controllers/Admin/StatusesController.php rename to src/Http/Controllers/StatusesController.php index d064078..152686f 100644 --- a/src/Http/Controllers/Admin/StatusesController.php +++ b/src/Http/Controllers/StatusesController.php @@ -1,14 +1,17 @@ - */ class StatusesController extends Controller @@ -18,7 +21,15 @@ class StatusesController extends Controller | ----------------------------------------------------------------- */ - use JsonResponses; + use HasNotifications; + + /* ----------------------------------------------------------------- + | Properties + | ----------------------------------------------------------------- + */ + + /** @var \Arcanesoft\Backups\Services\BackupService */ + protected $backupService; /* ----------------------------------------------------------------- | Constructor @@ -28,12 +39,14 @@ class StatusesController extends Controller /** * StatusesController constructor. */ - public function __construct() + public function __construct(BackupService $backupService) { parent::__construct(); - $this->setCurrentPage('backups-statuses'); - $this->addBreadcrumbRoute(trans('backups::statuses.titles.backups'), 'admin::backups.statuses.index'); + $this->setCurrentSidebarItem('foundation::backups'); + $this->addBreadcrumbRoute(__('Backups'), 'admin::backups.statuses.index'); + + $this->backupService = $backupService; } /* ----------------------------------------------------------------- @@ -43,55 +56,56 @@ public function __construct() public function index() { - $this->authorize(StatusesPolicy::PERMISSION_LIST); + $this->authorize(StatusesPolicy::ability('index')); - $statuses = BackupStatuses::all(); + $statuses = $this->backupService->statuses(); - $this->setTitle($title = trans('backups::statuses.titles.monitor-statuses-list')); + $this->setTitle($title = __('List of Monitor Statuses')); $this->addBreadcrumb($title); - return $this->view('admin.statuses.index', compact('statuses')); + return $this->view('statuses.index', compact('statuses')); } public function show($index) { - $this->authorize(StatusesPolicy::PERMISSION_SHOW); + $this->authorize(StatusesPolicy::ability('show')); - if (is_null($status = BackupStatuses::getStatus($index))) - self::pageNotFound(); + $status = $this->backupService->getStatus($index); - $backups = $status->backupDestination()->backups(); + abort_if(is_null($status), 404); - $this->setTitle($title = trans('backups::statuses.titles.monitor-status')); + $this->setTitle($title = __('Monitor Status')); $this->addBreadcrumb($title); - return $this->view('admin.statuses.show', compact('status', 'backups')); + return $this->view('statuses.show', compact('status')); } public function backup() { - $this->authorize(StatusesPolicy::PERMISSION_CREATE); + $this->authorize(StatusesPolicy::ability('create')); - if (BackupStatuses::runBackups()) { - return $this->jsonResponseSuccess([ + if ($this->backupService->runBackups()) { + return static::jsonResponseSuccess([ 'message' => $this->transNotification('created'), ]); } - return $this->jsonResponseError(['message' => 'There is an error while running the backups.']); + return static::jsonResponseError([ + 'message' => 'There is an error while running the backups.' + ]); } public function clear() { - $this->authorize(StatusesPolicy::PERMISSION_DELETE); + $this->authorize(StatusesPolicy::ability('clean')); - if (BackupStatuses::clearBackups()) { - return $this->jsonResponseSuccess([ + if ($this->backupService->clearBackups()) { + return static::jsonResponseSuccess([ 'message' => $this->transNotification('cleared'), ]); } - return $this->jsonResponseError(['message' => 'There is an error while running the backups.']); + return static::jsonResponseError(['message' => 'There is an error while running the backups.']); } /* ----------------------------------------------------------------- @@ -114,7 +128,8 @@ protected function transNotification($action, array $replace = [], array $contex $message = trans("backups::statuses.messages.{$action}.message", $replace); Log::info($message, $context); - $this->notifySuccess($message, $title); + + $this->notifySuccess($title, $message); return $message; } diff --git a/src/Http/Routes/AbstractRouteRegistrar.php b/src/Http/Routes/AbstractRouteRegistrar.php new file mode 100644 index 0000000..57c50ad --- /dev/null +++ b/src/Http/Routes/AbstractRouteRegistrar.php @@ -0,0 +1,34 @@ + + */ +abstract class AbstractRouteRegistrar extends AdminRouteRegistrar +{ + /* ----------------------------------------------------------------- + | Main Methods + | ----------------------------------------------------------------- + */ + + /** + * Group routes under a module stack. + * + * @param \Closure $callback + */ + protected function moduleGroup(Closure $callback): void + { + $this->prefix('backups') + ->name('backups.') + ->group($callback); + } +} diff --git a/src/Http/Routes/StatusesRoutes.php b/src/Http/Routes/StatusesRoutes.php index 418cf5d..8400013 100644 --- a/src/Http/Routes/StatusesRoutes.php +++ b/src/Http/Routes/StatusesRoutes.php @@ -1,6 +1,10 @@ - */ -class StatusesRoutes extends RouteRegistrar +class StatusesRoutes extends AbstractRouteRegistrar { /* ----------------------------------------------------------------- | Main Methods @@ -18,22 +22,28 @@ class StatusesRoutes extends RouteRegistrar /** * Map the routes for the application. */ - public function map() + public function map(): void { - $this->prefix('statuses')->as('statuses.')->group(function () { - $this->get('/', 'StatusesController@index') - ->name('index'); // admin::backups.statuses.index + $this->adminGroup(function () { + $this->prefix('statuses')->as('statuses.')->group(function () { + // admin::backups.statuses.index + $this->get('/', [StatusesController::class, 'index']) + ->name('index'); - $this->post('backup', 'StatusesController@backup') - ->middleware('ajax') - ->name('backup'); // admin::backups.statuses.backup + // admin::backups.statuses.backup + $this->post('backup', [StatusesController::class, 'backup']) + ->middleware(['ajax']) + ->name('backup'); - $this->post('clear', 'StatusesController@clear') - ->middleware('ajax') - ->name('clear'); // admin::backups.statuses.clear + // admin::backups.statuses.clear + $this->post('clear', [StatusesController::class, 'clear']) + ->middleware(['ajax']) + ->name('clear'); - $this->get('{index}', 'StatusesController@show') - ->name('show'); // admin::backups.statuses.clear + // admin::backups.statuses.clear + $this->get('{index}', [StatusesController::class, 'show']) + ->name('show'); + }); }); } } diff --git a/src/Policies/StatusesPolicy.php b/src/Policies/StatusesPolicy.php index 754c66e..ff8cd41 100644 --- a/src/Policies/StatusesPolicy.php +++ b/src/Policies/StatusesPolicy.php @@ -1,25 +1,78 @@ - */ class StatusesPolicy extends Policy { /* ----------------------------------------------------------------- - | Constants + | Getters + | ----------------------------------------------------------------- + */ + + /** + * Get the ability's prefix. + * + * @return string + */ + protected static function prefix(): string + { + return 'admin::backups.statuses.'; + } + + /* ----------------------------------------------------------------- + | Main Methods | ----------------------------------------------------------------- */ - const PERMISSION_LIST = 'backups.statuses.list'; - const PERMISSION_SHOW = 'backups.statuses.show'; - const PERMISSION_CREATE = 'backups.statuses.create'; - const PERMISSION_DELETE = 'backups.statuses.delete'; + /** + * Get the policy's abilities. + * + * @return \Arcanedev\LaravelPolicies\Ability[]|iterable + */ + public function abilities(): iterable + { + $this->setMetas([ + 'category' => 'Statuses', + ]); + + return [ + + // admin::backups.statuses.index + $this->makeAbility('index')->setMetas([ + 'name' => 'Show all backup statuses', + 'description' => 'Ability to list all backup statuses', + ]), + + // admin::backups.statuses.show + $this->makeAbility('show')->setMetas([ + 'name' => 'Show a backup status', + 'description' => 'Ability to show a backup status', + ]), + + // admin::backups.statuses.create + $this->makeAbility('create')->setMetas([ + 'name' => 'Create a backup', + 'description' => 'Ability to create a backup', + ]), + + // admin::backups.statuses.clean + $this->makeAbility('clean')->setMetas([ + 'name' => 'Clean backups', + 'description' => 'Ability to clean old backups', + ]), + + ]; + } /* ----------------------------------------------------------------- | Abilities @@ -29,48 +82,48 @@ class StatusesPolicy extends Policy /** * Allow to list all the backups. * - * @param \Arcanesoft\Contracts\Auth\Models\User $user + * @param \Arcanesoft\Foundation\Authorization\Models\Administrator|mixed $administrator * - * @return bool + * @return \Illuminate\Auth\Access\Response|bool|void */ - public function listPolicy(User $user) + public function index(Administrator $administrator) { - return $user->may(static::PERMISSION_LIST); + // } /** * Allow to display a backup. * - * @param \Arcanesoft\Contracts\Auth\Models\User $user + * @param \Arcanesoft\Foundation\Authorization\Models\Administrator|mixed $administrator * - * @return bool + * @return \Illuminate\Auth\Access\Response|bool|void */ - public function showPolicy(User $user) + public function show(Administrator $administrator) { - return $user->may(static::PERMISSION_SHOW); + // } /** * Allow to create a backup. * - * @param \Arcanesoft\Contracts\Auth\Models\User $user + * @param \Arcanesoft\Foundation\Authorization\Models\Administrator|mixed $administrator * - * @return bool + * @return \Illuminate\Auth\Access\Response|bool|void */ - public function createPolicy(User $user) + public function create(Administrator $administrator) { - return $user->may(static::PERMISSION_CREATE); + // } /** - * Allow to delete a backup. + * Allow to clean backups. * - * @param \Arcanesoft\Contracts\Auth\Models\User $user + * @param \Arcanesoft\Foundation\Authorization\Models\Administrator|mixed $administrator * - * @return bool + * @return \Illuminate\Auth\Access\Response|bool|void */ - public function deletePolicy(User $user) + public function clean(Administrator $administrator) { - return $user->may(static::PERMISSION_DELETE); + // } } diff --git a/src/Providers/AuthServiceProvider.php b/src/Providers/AuthServiceProvider.php new file mode 100644 index 0000000..d0e28a7 --- /dev/null +++ b/src/Providers/AuthServiceProvider.php @@ -0,0 +1,30 @@ + + */ +class AuthServiceProvider extends ServiceProvider +{ + /* ----------------------------------------------------------------- + | Getters + | ----------------------------------------------------------------- + */ + + /** + * Get policy's classes. + * + * @return iterable + */ + public function policyClasses(): iterable + { + return $this->app->get('config')->get('arcanesoft.backups.policies', []); + } +} diff --git a/src/Providers/AuthorizationServiceProvider.php b/src/Providers/AuthorizationServiceProvider.php deleted file mode 100644 index b73898f..0000000 --- a/src/Providers/AuthorizationServiceProvider.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ -class AuthorizationServiceProvider extends ServiceProvider -{ - /* ----------------------------------------------------------------- - | Main Methods - | ----------------------------------------------------------------- - */ - - /** - * Register any application authentication / authorization services. - */ - public function boot() - { - parent::registerPolicies(); - - $this->defineMany(StatusesPolicy::class, StatusesPolicy::policies()); - } -} diff --git a/src/Providers/CommandServiceProvider.php b/src/Providers/CommandServiceProvider.php deleted file mode 100644 index 4e8e73c..0000000 --- a/src/Providers/CommandServiceProvider.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ -class CommandServiceProvider extends ServiceProvider -{ - /* ----------------------------------------------------------------- - | Properties - | ----------------------------------------------------------------- - */ - - /** - * The commands to be registered. - * - * @var array - */ - protected $commands = [ - InstallCommand::class, - PublishCommand::class, - ]; -} diff --git a/src/Providers/PackagesServiceProvider.php b/src/Providers/PackagesServiceProvider.php deleted file mode 100644 index 836a65d..0000000 --- a/src/Providers/PackagesServiceProvider.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ -class PackagesServiceProvider extends ServiceProvider -{ - /* ----------------------------------------------------------------- - | Main Methods - | ----------------------------------------------------------------- - */ - - /** - * Register the service provider. - */ - public function register() - { - parent::register(); - - $this->registerSpatieBackupPackage(); - } - - /* ----------------------------------------------------------------- - | Other Methods - | ----------------------------------------------------------------- - */ - - /** - * Register Spatie backup package. - */ - private function registerSpatieBackupPackage() - { - $this->registerProvider(\Spatie\Backup\BackupServiceProvider::class); - } -} diff --git a/src/Providers/RouteServiceProvider.php b/src/Providers/RouteServiceProvider.php index 557b5ff..8d02204 100644 --- a/src/Providers/RouteServiceProvider.php +++ b/src/Providers/RouteServiceProvider.php @@ -1,60 +1,33 @@ - */ class RouteServiceProvider extends ServiceProvider { - /* ----------------------------------------------------------------- - | Properties - | ----------------------------------------------------------------- - */ - - /** - * The admin controller namespace for the application. - * - * @var string - */ - protected $adminNamespace = 'Arcanesoft\\Backups\\Http\\Controllers\\Admin'; - /* ----------------------------------------------------------------- | Main Methods | ----------------------------------------------------------------- */ /** - * Register the route bindings. - */ - protected function registerRouteBindings() - { - // - } - - /** - * Define the routes for the application. - */ - public function map() - { - $this->adminGroup(function () { - $this->mapAdminRoutes(); - }); - } - - /** - * Define the admin routes for the application. + * Get the registered routes. + * + * @return array */ - private function mapAdminRoutes() + public function routeClasses(): array { - $this->name('backups.') - ->prefix($this->config()->get('arcanesoft.backups.route.prefix', 'backups')) - ->group(function () { - Routes\StatusesRoutes::register(); - }); + return [ + Routes\StatusesRoutes::class + ]; } } diff --git a/src/Seeds/DatabaseSeeder.php b/src/Seeds/DatabaseSeeder.php deleted file mode 100644 index 2fd46b4..0000000 --- a/src/Seeds/DatabaseSeeder.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ -class DatabaseSeeder extends Seeder -{ - /* ----------------------------------------------------------------- - | Properties - | ----------------------------------------------------------------- - */ - - /** - * Seeders collection. - * - * @var array - */ - protected $seeds = [ - PermissionsTableSeeder::class, - RolesTableSeeder::class, - ]; -} diff --git a/src/Seeds/PermissionsTableSeeder.php b/src/Seeds/PermissionsTableSeeder.php deleted file mode 100644 index 972cbc0..0000000 --- a/src/Seeds/PermissionsTableSeeder.php +++ /dev/null @@ -1,73 +0,0 @@ - - */ -class PermissionsTableSeeder extends PermissionsSeeder -{ - /* ----------------------------------------------------------------- - | Main Methods - | ----------------------------------------------------------------- - */ - - /** - * Run the database seeds. - */ - public function run() - { - $this->seed([ - [ - 'group' => [ - 'name' => 'Backups', - 'slug' => 'backups', - 'description' => 'backups permissions group', - ], - 'permissions' => array_merge( - $this->getStatusesPermissions() - ), - ], - ]); - } - - /* ----------------------------------------------------------------- - | Other Methods - | ----------------------------------------------------------------- - */ - - /** - * Get the Statuses permissions. - * - * @return array - */ - private function getStatusesPermissions() - { - return [ - [ - 'name' => 'Statuses - List all backups', - 'description' => 'Allow to list all posts.', - 'slug' => StatusesPolicy::PERMISSION_LIST, - ], - [ - 'name' => 'Statuses - View a backup', - 'description' => 'Allow to display a post.', - 'slug' => StatusesPolicy::PERMISSION_SHOW, - ], - [ - 'name' => 'Statuses - Create a backup', - 'description' => 'Allow to create a post.', - 'slug' => StatusesPolicy::PERMISSION_CREATE, - ], - [ - 'name' => 'Statuses - Delete a backup', - 'description' => 'Allow to delete a post.', - 'slug' => StatusesPolicy::PERMISSION_DELETE, - ], - ]; - } -} diff --git a/src/Services/BackupService.php b/src/Services/BackupService.php new file mode 100644 index 0000000..e6ef195 --- /dev/null +++ b/src/Services/BackupService.php @@ -0,0 +1,119 @@ + + */ +class BackupService +{ + /* ----------------------------------------------------------------- + | Properties + | ----------------------------------------------------------------- + */ + + /** @var \Arcanedev\LaravelBackup\Actions\Backup\BackupAction */ + protected $backupAction; + + /** @var \Arcanedev\LaravelBackup\Actions\Cleanup\CleanAction */ + protected $cleanAction; + + /* ----------------------------------------------------------------- + | Constructor + | ----------------------------------------------------------------- + */ + + /** + * BackupService constructor. + * + * @param \Arcanedev\LaravelBackup\Actions\Backup\BackupAction $backupAction + * @param \Arcanedev\LaravelBackup\Actions\Cleanup\CleanAction $cleanAction + */ + public function __construct(BackupAction $backupAction, CleanAction $cleanAction) + { + $this->backupAction = $backupAction; + $this->cleanAction = $cleanAction; + } + + /* ----------------------------------------------------------------- + | Main Methods + | ----------------------------------------------------------------- + */ + + /** + * Get all the statuses. + * + * @return \Arcanedev\LaravelBackup\Entities\BackupDestinationStatus[]|\Arcanedev\LaravelBackup\Entities\BackupDestinationStatusCollection + */ + public function statuses(): BackupDestinationStatusCollection + { + return BackupDestinationStatusCollection::makeFromConfig(); + } + + /** + * Get a status by index. + * + * @param int $index + * + * @return \Arcanedev\LaravelBackup\Entities\BackupDestinationStatus|null + */ + public function getStatus($index): ?BackupDestinationStatus + { + return $this->statuses()->get($index); + } + + /** + * Run the backups. + * + * @param string|null $disk + * + * @return bool + */ + public function runBackups($disk = null): bool + { + $options = [ + 'filename' => null, + 'only-db' => false, + 'db-name' => [], + 'only-files' => false, + 'only-to-disk' => $disk, + 'disable-notifications' => false, + ]; + + try { + $this->backupAction->execute($options); + + return true; + } + catch (\Exception $ex) { + return false; + } + } + + /** + * Clean the backups. + * + * @return bool + */ + public function clearBackups(): bool + { + try { + $this->cleanAction->execute([ + // + ]); + + return true; + } + catch (\Exception $ex) { + return false; + } + } +} diff --git a/src/Services/BackupStatuses.php b/src/Services/BackupStatuses.php deleted file mode 100644 index 79e30f7..0000000 --- a/src/Services/BackupStatuses.php +++ /dev/null @@ -1,92 +0,0 @@ - - */ -class BackupStatuses -{ - /* ----------------------------------------------------------------- - | Main Methods - | ----------------------------------------------------------------- - */ - - /** - * Get all the statuses. - * - * @return \Illuminate\Support\Collection - */ - public static function all() - { - return BackupDestinationStatusFactory::createForMonitorConfig(config('laravel-backup.monitorBackups')); - } - - /** - * Get a status by index. - * - * @param int $index - * - * @return \Spatie\Backup\Tasks\Monitor\BackupDestinationStatus|null - */ - public static function getStatus($index) - { - return static::all()->get($index); - } - - /** - * Run the backups. - * - * @param string|null $disk - * - * @return bool - */ - public static function runBackups($disk = null) - { - try { - $backupJob = BackupJobFactory::createFromArray(config('laravel-backup')); - - if ( ! is_null($disk)) { - $backupJob->onlyBackupTo($disk); - } - - $backupJob->run(); - } - catch (\Exception $ex) { - return false; - } - - return true; - } - - /** - * Clean the backups. - * - * @return bool - */ - public static function clearBackups() - { - try { - $config = config('laravel-backup'); - - $backupDestinations = BackupDestinationFactory::createFromArray($config['backup']); - - $strategy = app($config['cleanup']['strategy']); - - $disableNotification = false; // TODO: Create a config for this - - (new CleanupJob($backupDestinations, $strategy, $disableNotification))->run(); - } - catch (\Exception $ex) { - return false; - } - - return true; - } -} diff --git a/tests/Feature/.gitkeep b/tests/Feature/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/TestCase.php b/tests/TestCase.php index 52df8a2..3720a80 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,11 +1,14 @@ - */ abstract class TestCase extends BaseTestCase diff --git a/tests/Unit/.gitkeep b/tests/Unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/BackupsServiceProviderTest.php b/tests/Unit/BackupsServiceProviderTest.php similarity index 94% rename from tests/BackupsServiceProviderTest.php rename to tests/Unit/BackupsServiceProviderTest.php index 13cdf6a..4e2bc78 100644 --- a/tests/BackupsServiceProviderTest.php +++ b/tests/Unit/BackupsServiceProviderTest.php @@ -1,11 +1,15 @@ - */ class BackupsServiceProviderTest extends TestCase diff --git a/translations/fr.json b/translations/fr.json new file mode 100644 index 0000000..b3f78a2 --- /dev/null +++ b/translations/fr.json @@ -0,0 +1,10 @@ +{ + "Backups": "Sauvegardes", + "Monitor Statuses": "Surveiller les états", + "List of Monitor Statuses": "Liste des états du moniteur", + "Disk": "Disque", + "Reachable": "Accessible", + "Healthy": "Sain", + "Newest Backup": "Dernière sauvegarde", + "Used Storage": "Stockage utilisé" +} diff --git a/views/statuses/index.blade.php b/views/statuses/index.blade.php new file mode 100644 index 0000000..c055939 --- /dev/null +++ b/views/statuses/index.blade.php @@ -0,0 +1,158 @@ + + @section('page-title') + @lang('Backups') + @endsection + + + +
+ @lang('Monitor Statuses') +
+ @can(Arcanesoft\Backups\Policies\StatusesPolicy::ability('create')) + + @lang('Run Backup') + + @endcan + + @can(Arcanesoft\Backups\Policies\StatusesPolicy::ability('delete')) + + @endcan +
+
+
+ + + + + + + + + + + + + + + @forelse($statuses as $index => $status) + backupDestination() + ?> + + {{ $destination->diskName() }} + {{ $destination->backupName() }} + + @if ($destination->isReachable()) + + @else + + @endif + + + @if ($status->isHealthy()) + + @else + + @endif + + + @if ($destination->isReachable()) + + @else + + @endif + + + @if ($destination->isReachable() && $destination->newestBackup()) + {{ $destination->newestBackup()->date()->diffForHumans() ?: 'No backups present' }} + @else + + @endif + + + + + + @can(Arcanesoft\Backups\Policies\StatusesPolicy::ability('show')) + + @endcan + + + @empty + @endforelse + + +
+ + {{-- CREATE BACKUP MODAL/SCRIPT --}} + @can(Arcanesoft\Backups\Policies\StatusesPolicy::ability('create')) + @push('modals') + + + + @lang('Run Backup') + + @lang('Are you sure you want to run the backup ?') + + + + + + + @endpush + + @push('scripts') + + @endpush + @endcan + + + @can(Arcanesoft\Backups\Policies\StatusesPolicy::ability('delete')) + @push('modals') + + + + @lang('Cleanup Backups') + + @lang('Are you sure you want to cleanup the backups ?') + + + + + + + @endpush + + @push('scripts') + + @endpush + @endcan +
diff --git a/views/statuses/show.blade.php b/views/statuses/show.blade.php new file mode 100644 index 0000000..0f99fa7 --- /dev/null +++ b/views/statuses/show.blade.php @@ -0,0 +1,110 @@ +backupDestination() +?> + + + @section('page-title') + @lang('Backups') + @endsection + +
+
+ + @lang('Monitor Status') + + + + {{ $destination->backupName() }} + + + + {{ $destination->diskName() }} + + + + + @if ($destination->isReachable()) + + @else + + @endif + + + + + + @if ($status->isHealthy()) + + @else + + @endif + + + + + + @if ($destination->isReachable()) + + @else + + @endif + + + + + + @if ($destination->isReachable() && $destination->newestBackup()) + {{ $destination->newestBackup()->date()->diffForHumans() ?: 'null' }} + @else + + @endif + + + + + + + + + + +
+ +
+ {{-- BACKUPS --}} + + @lang('Backups') + + + + + + + + + + @forelse ($destination->backups() as $backup) + + + + {{ $backup->date() }} + + + {{ $backup->path() }} + + + {{ $backup->humanReadableSize() }} + + + @empty + + @lang('There is no backups for the time being') + + @endforelse + + + +
+
+