diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 7c21fb282..a995adcc5 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,9 +2,9 @@ namespace App\Console; -use App\Jobs\BackupDatabaseJob; use App\Jobs\CheckResaleLicenseJob; use App\Jobs\CheckResaleLicenseKeys; +use App\Jobs\DatabaseBackupJob; use App\Jobs\DockerCleanupJob; use App\Jobs\InstanceApplicationsStatusJob; use App\Jobs\InstanceAutoUpdateJob; @@ -50,7 +50,7 @@ private function check_scheduled_backups($schedule) if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) { $scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency]; } - $schedule->job(new BackupDatabaseJob( + $schedule->job(new DatabaseBackupJob( backup: $scheduled_backup ))->cron($scheduled_backup->frequency); } diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php index 2bcc23863..4c02c8bc2 100644 --- a/app/Http/Controllers/DatabaseController.php +++ b/app/Http/Controllers/DatabaseController.php @@ -26,6 +26,29 @@ public function configuration() return view('project.database.configuration', ['database' => $database]); } + public function backup_logs() + { + $backup_uuid = request()->route('backup_uuid'); + $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + if (!$project) { + return redirect()->route('dashboard'); + } + $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']); + if (!$environment) { + return redirect()->route('dashboard'); + } + $database = $environment->databases->where('uuid', request()->route('database_uuid'))->first(); + if (!$database) { + return redirect()->route('dashboard'); + } + $backup = $database->scheduledBackups->where('uuid', $backup_uuid)->first(); + if (!$backup) { + return redirect()->route('dashboard'); + } + $backup_executions = collect($backup->executions)->sortByDesc('created_at'); + return view('project.database.backups.logs', ['database' => $database, 'backup' => $backup, 'backup_executions' => $backup_executions]); + } + public function backups() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); @@ -40,6 +63,6 @@ public function backups() if (!$database) { return redirect()->route('dashboard'); } - return view('project.database.backups', ['database' => $database]); + return view('project.database.backups.all', ['database' => $database]); } } diff --git a/app/Http/Livewire/Project/Database/BackupEdit.php b/app/Http/Livewire/Project/Database/BackupEdit.php new file mode 100644 index 000000000..b790689e2 --- /dev/null +++ b/app/Http/Livewire/Project/Database/BackupEdit.php @@ -0,0 +1,41 @@ + 'required|boolean', + 'backup.frequency' => 'required|string', + 'backup.number_of_backups_locally' => 'required|integer|min:1', + ]; + protected $validationAttributes = [ + 'backup.enabled' => 'Enabled', + 'backup.frequency' => 'Frequency', + 'backup.number_of_backups_locally' => 'Number of Backups Locally', + ]; + + public function instantSave() + { + $this->backup->save(); + $this->backup->refresh(); + $this->emit('success', 'Backup updated successfully'); + } + + public function submit() + { + $isValid = validate_cron_expression($this->backup->frequency); + if (!$isValid) { + $this->emit('error', 'Invalid Cron / Human expression'); + return; + } + $this->validate(); + $this->backup->save(); + $this->backup->refresh(); + $this->emit('success', 'Backup updated successfully'); + } +} diff --git a/app/Http/Livewire/Project/Database/BackupExecution.php b/app/Http/Livewire/Project/Database/BackupExecution.php new file mode 100644 index 000000000..5e48bbec4 --- /dev/null +++ b/app/Http/Livewire/Project/Database/BackupExecution.php @@ -0,0 +1,24 @@ +execution->filename, $this->execution->scheduledDatabaseBackup->database->destination->server); + $this->execution->delete(); + $this->emit('success', 'Backup execution deleted successfully.'); + $this->emit('refreshBackupExecutions'); + } +} diff --git a/app/Http/Livewire/Project/Database/BackupExecutions.php b/app/Http/Livewire/Project/Database/BackupExecutions.php new file mode 100644 index 000000000..a4d034ab9 --- /dev/null +++ b/app/Http/Livewire/Project/Database/BackupExecutions.php @@ -0,0 +1,17 @@ +executions = collect($this->backup->executions)->sortByDesc('created_at'); + } +} diff --git a/app/Http/Livewire/Project/Database/CreateScheduledBackup.php b/app/Http/Livewire/Project/Database/CreateScheduledBackup.php index b5593cd71..c2334ca2d 100644 --- a/app/Http/Livewire/Project/Database/CreateScheduledBackup.php +++ b/app/Http/Livewire/Project/Database/CreateScheduledBackup.php @@ -4,24 +4,20 @@ use App\Models\ScheduledDatabaseBackup; use Livewire\Component; -use Poliander\Cron\CronExpression; class CreateScheduledBackup extends Component { public $database; public $frequency; public bool $enabled = true; - public bool $keep_locally = true; public bool $save_s3 = true; protected $rules = [ 'frequency' => 'required|string', - 'keep_locally' => 'required|boolean', 'save_s3' => 'required|boolean', ]; protected $validationAttributes = [ 'frequency' => 'Backup Frequency', - 'keep_locally' => 'Keep Locally', 'save_s3' => 'Save to S3', ]; @@ -29,13 +25,7 @@ public function submit(): void { try { $this->validate(); - - $expression = new CronExpression($this->frequency); - $isValid = $expression->isValid(); - - if (isset(VALID_CRON_STRINGS[$this->frequency])) { - $isValid = true; - } + $isValid = validate_cron_expression($this->frequency); if (!$isValid) { $this->emit('error', 'Invalid Cron / Human expression'); return; @@ -43,7 +33,6 @@ public function submit(): void ScheduledDatabaseBackup::create([ 'enabled' => true, 'frequency' => $this->frequency, - 'keep_locally' => $this->keep_locally, 'save_s3' => $this->save_s3, 'database_id' => $this->database->id, 'database_type' => $this->database->getMorphClass(), @@ -54,7 +43,6 @@ public function submit(): void general_error_handler($e, $this); } finally { $this->frequency = ''; - $this->keep_locally = true; $this->save_s3 = true; } } diff --git a/app/Http/Livewire/Project/Database/ScheduledBackups.php b/app/Http/Livewire/Project/Database/ScheduledBackups.php index 033f127e7..f1abbb86d 100644 --- a/app/Http/Livewire/Project/Database/ScheduledBackups.php +++ b/app/Http/Livewire/Project/Database/ScheduledBackups.php @@ -7,9 +7,22 @@ class ScheduledBackups extends Component { public $database; + public $parameters; protected $listeners = ['refreshScheduledBackups']; - public function refreshScheduledBackups() + public function mount(): void + { + $this->parameters = get_route_parameters(); + } + + public function delete($scheduled_backup_id): void + { + $this->database->scheduledBackups->find($scheduled_backup_id)->delete(); + $this->emit('success', 'Scheduled backup deleted successfully.'); + $this->refreshScheduledBackups(); + } + + public function refreshScheduledBackups(): void { ray('refreshScheduledBackups'); $this->database->refresh(); diff --git a/app/Jobs/BackupDatabaseJob.php b/app/Jobs/BackupDatabaseJob.php deleted file mode 100644 index 7cc7471f3..000000000 --- a/app/Jobs/BackupDatabaseJob.php +++ /dev/null @@ -1,78 +0,0 @@ -backup = $backup; - $this->team = Team::find($backup->team_id); - $this->database = $this->backup->database->first(); - $this->database_type = $this->database->type(); - $this->server = $this->database->destination->server; - $this->status = $this->database->status; - } - - public function middleware(): array - { - return [new WithoutOverlapping($this->backup->id)]; - } - - public function uniqueId(): int - { - return $this->backup->id; - } - - public function handle() - { - if ($this->status !== 'running') { - ray('database not running'); - return; - } - if ($this->database_type === 'standalone-postgresql') { - $this->backup_standalone_postgresql(); - } - } - - private function backup_standalone_postgresql() - { - try { - $backup_filename = backup_dir() . "/{$this->database->uuid}/dumpall-" . Carbon::now()->timestamp . ".sql"; - $commands[] = "mkdir -p " . backup_dir(); - $commands[] = "mkdir -p " . backup_dir() . "/{$this->database->uuid}"; - $commands[] = "docker exec {$this->database->uuid} pg_dumpall -U {$this->database->postgres_user} > $backup_filename"; - instant_remote_process($commands, $this->server); - ray('Backup done for ' . $this->database->uuid . ' at ' . $this->server->name . ':' . $backup_filename); - if (!$this->backup->keep_locally) { - $commands[] = "rm -rf $backup_filename"; - instant_remote_process($commands, $this->server); - } - } catch (Throwable $th) { - ray($th); - //throw $th; - } - } -} diff --git a/app/Jobs/DatabaseBackupJob.php b/app/Jobs/DatabaseBackupJob.php new file mode 100644 index 000000000..e6cedabc7 --- /dev/null +++ b/app/Jobs/DatabaseBackupJob.php @@ -0,0 +1,142 @@ +backup = $backup; + $this->team = Team::find($backup->team_id); + $this->database = $this->backup->database->first(); + $this->database_type = $this->database->type(); + $this->server = $this->database->destination->server; + $this->database_status = $this->database->status; + } + + public function middleware(): array + { + return [new WithoutOverlapping($this->backup->id)]; + } + + public function uniqueId(): int + { + return $this->backup->id; + } + + public function handle() + { + if ($this->database_status !== 'running') { + ray('database not running'); + return; + } + $this->backup_filename = backup_dir() . "/{$this->database->uuid}/dumpall-" . Carbon::now()->timestamp . ".sql"; + + $this->backup_log = ScheduledDatabaseBackupExecution::create([ + 'filename' => $this->backup_filename, + 'scheduled_database_backup_id' => $this->backup->id, + ]); + if ($this->database_type === 'standalone-postgresql') { + $this->backup_standalone_postgresql(); + } + $this->calculate_size(); + $this->remove_old_backups(); + $this->save_backup_logs(); + } + + private function backup_standalone_postgresql() + { + try { + $commands[] = "mkdir -p " . backup_dir(); + $commands[] = "mkdir -p " . backup_dir() . "/{$this->database->uuid}"; + $commands[] = "docker exec {$this->database->uuid} pg_dumpall -U {$this->database->postgres_user} > $this->backup_filename"; + + $this->backup_output = instant_remote_process($commands, $this->server); + + $this->backup_output = trim($this->backup_output); + + if ($this->backup_output === '') { + $this->backup_output = null; + } + + ray('Backup done for ' . $this->database->uuid . ' at ' . $this->server->name . ':' . $this->backup_filename); + + $this->backup_status = 'success'; + } catch (Throwable $th) { + $this->backup_status = 'failed'; + $this->add_to_backup_output($th->getMessage()); + ray('Backup failed for ' . $this->database->uuid . ' at ' . $this->server->name . ':' . $this->backup_filename . '\n\nError:' . $th->getMessage()); + } finally { + $this->backup_log->update([ + 'status' => $this->backup_status, + ]); + } + } + + private function add_to_backup_output($output) + { + if ($this->backup_output) { + $this->backup_output = $this->backup_output . "\n" . $output; + } else { + $this->backup_output = $output; + } + } + + private function calculate_size() + { + $this->size = instant_remote_process(["du -b $this->backup_filename | cut -f1"], $this->server); + } + + private function remove_old_backups() + { + if ($this->backup->number_of_backups_locally === 0) { + $deletable = $this->backup->executions()->where('status', 'success'); + } else { + $deletable = $this->backup->executions()->where('status', 'success')->orderByDesc('created_at')->skip($this->backup->number_of_backups_locally); + } + ray($deletable->get()); + foreach ($deletable->get() as $execution) { + delete_backup_locally($execution->filename, $this->server); + $execution->delete(); + } + } + + private function save_backup_logs() + { + $this->backup_log->update([ + 'status' => $this->backup_status, + 'message' => $this->backup_output, + 'size' => $this->size, + ]); + + } +} diff --git a/app/Models/ScheduledDatabaseBackup.php b/app/Models/ScheduledDatabaseBackup.php index 5ecd5e1b0..795d4b9c8 100644 --- a/app/Models/ScheduledDatabaseBackup.php +++ b/app/Models/ScheduledDatabaseBackup.php @@ -3,12 +3,26 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\MorphTo; + class ScheduledDatabaseBackup extends BaseModel { protected $guarded = []; - public function database() + public function database(): MorphTo { return $this->morphTo(); } + + public function latest_log(): HasOne + { + return $this->hasOne(ScheduledDatabaseBackupExecution::class)->latest(); + } + + public function executions(): HasMany + { + return $this->hasMany(ScheduledDatabaseBackupExecution::class); + } } diff --git a/app/Models/ScheduledDatabaseBackupExecution.php b/app/Models/ScheduledDatabaseBackupExecution.php new file mode 100644 index 000000000..b06dd5b45 --- /dev/null +++ b/app/Models/ScheduledDatabaseBackupExecution.php @@ -0,0 +1,15 @@ +belongsTo(ScheduledDatabaseBackup::class); + } +} diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 58284307b..ccfaae040 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -64,11 +64,6 @@ public function destination() return $this->morphTo(); } - public function scheduled_database_backups() - { - return $this->morphMany(ScheduledDatabaseBackup::class, 'database'); - } - public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class); diff --git a/bootstrap/helpers/constants.php b/bootstrap/helpers/constants.php index f3cc934e6..0e42b311e 100644 --- a/bootstrap/helpers/constants.php +++ b/bootstrap/helpers/constants.php @@ -2,6 +2,7 @@ const DATABASE_TYPES = ['postgresql']; const VALID_CRON_STRINGS = [ + 'every_minute' => '* * * * *', 'hourly' => '0 * * * *', 'daily' => '0 0 * * *', 'weekly' => '0 0 * * 0', diff --git a/bootstrap/helpers/databases.php b/bootstrap/helpers/databases.php index 497d809a2..f6dc72f66 100644 --- a/bootstrap/helpers/databases.php +++ b/bootstrap/helpers/databases.php @@ -1,5 +1,6 @@ $destination->id, 'destination_type' => $destination->getMorphClass(), ]); - +} + +/** + * Delete file locally on the filesystem. + * @param string $filename + * @param Server $server + * @return void + */ +function delete_backup_locally(string|null $filename, Server $server): void +{ + if (empty($filename)) { + return; + } + instant_remote_process(["rm -f \"{$filename}\""], $server, throwError: false); } diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index fed4a418f..5dbae95b2 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -6,6 +6,7 @@ use Illuminate\Support\Facades\Route; use Illuminate\Support\Str; use Nubs\RandomNameGenerator\All; +use Poliander\Cron\CronExpression; use Visus\Cuid2\Cuid2; function application_configuration_dir(): string @@ -166,3 +167,16 @@ function is_cloud(): bool return !config('coolify.self_hosted'); } +function validate_cron_expression($expression_to_validate): bool +{ + $isValid = false; + $expression = new CronExpression($expression_to_validate); + $isValid = $expression->isValid(); + + if (isset(VALID_CRON_STRINGS[$expression_to_validate])) { + $isValid = true; + } + return $isValid; +} + + diff --git a/composer.lock b/composer.lock index ee52ea77c..a0558a682 100644 --- a/composer.lock +++ b/composer.lock @@ -1815,16 +1815,16 @@ }, { "name": "laravel/framework", - "version": "v10.16.1", + "version": "v10.18.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "5c93d2795c393b462481179ce42dedfb30cc19b5" + "reference": "9d41928900f7ecf409627a7d06c0a4dfecff2ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/5c93d2795c393b462481179ce42dedfb30cc19b5", - "reference": "5c93d2795c393b462481179ce42dedfb30cc19b5", + "url": "https://api.github.com/repos/laravel/framework/zipball/9d41928900f7ecf409627a7d06c0a4dfecff2ea7", + "reference": "9d41928900f7ecf409627a7d06c0a4dfecff2ea7", "shasum": "" }, "require": { @@ -1842,11 +1842,12 @@ "ext-tokenizer": "*", "fruitcake/php-cors": "^1.2", "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.1", "laravel/serializable-closure": "^1.3", "league/commonmark": "^2.2.1", "league/flysystem": "^3.8.0", "monolog/monolog": "^3.0", - "nesbot/carbon": "^2.62.1", + "nesbot/carbon": "^2.67", "nunomaduro/termwind": "^1.13", "php": "^8.1", "psr/container": "^1.1.1|^2.0.1", @@ -1925,7 +1926,6 @@ "mockery/mockery": "^1.5.1", "orchestra/testbench-core": "^8.4", "pda/pheanstalk": "^4.0", - "phpstan/phpdoc-parser": "^1.15", "phpstan/phpstan": "^1.4.7", "phpunit/phpunit": "^10.0.7", "predis/predis": "^2.0.2", @@ -2011,20 +2011,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2023-07-26T03:30:46+00:00" + "time": "2023-08-08T14:30:38+00:00" }, { "name": "laravel/horizon", - "version": "v5.19.0", + "version": "v5.19.1", "source": { "type": "git", "url": "https://github.com/laravel/horizon.git", - "reference": "1c9b6b3068c64f50ae99a96ca662206c6078a1c5" + "reference": "1987f98084bc3119f78ec3da6283821a2c1acf63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/1c9b6b3068c64f50ae99a96ca662206c6078a1c5", - "reference": "1c9b6b3068c64f50ae99a96ca662206c6078a1c5", + "url": "https://api.github.com/repos/laravel/horizon/zipball/1987f98084bc3119f78ec3da6283821a2c1acf63", + "reference": "1987f98084bc3119f78ec3da6283821a2c1acf63", "shasum": "" }, "require": { @@ -2087,9 +2087,57 @@ ], "support": { "issues": "https://github.com/laravel/horizon/issues", - "source": "https://github.com/laravel/horizon/tree/v5.19.0" + "source": "https://github.com/laravel/horizon/tree/v5.19.1" }, - "time": "2023-07-14T14:18:51+00:00" + "time": "2023-08-09T13:18:44+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.1.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "1b3ab520a75eddefcda99f49fb551d231769b1fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/1b3ab520a75eddefcda99f49fb551d231769b1fa", + "reference": "1b3ab520a75eddefcda99f49fb551d231769b1fa", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.4" + }, + "time": "2023-08-07T13:14:59+00:00" }, { "name": "laravel/sanctum", @@ -2882,16 +2930,16 @@ }, { "name": "livewire/livewire", - "version": "v2.12.3", + "version": "v2.12.5", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "019b1e69d8cd8c7e749eba7a38e4fa69ecbc8f74" + "reference": "96a249f5ab51d8377817d802f91d1e440869c1d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/019b1e69d8cd8c7e749eba7a38e4fa69ecbc8f74", - "reference": "019b1e69d8cd8c7e749eba7a38e4fa69ecbc8f74", + "url": "https://api.github.com/repos/livewire/livewire/zipball/96a249f5ab51d8377817d802f91d1e440869c1d6", + "reference": "96a249f5ab51d8377817d802f91d1e440869c1d6", "shasum": "" }, "require": { @@ -2943,7 +2991,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v2.12.3" + "source": "https://github.com/livewire/livewire/tree/v2.12.5" }, "funding": [ { @@ -2951,20 +2999,20 @@ "type": "github" } ], - "time": "2023-03-03T20:12:38+00:00" + "time": "2023-08-02T06:31:31+00:00" }, { "name": "masmerise/livewire-toaster", - "version": "1.2.1", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/masmerise/livewire-toaster.git", - "reference": "a47875b10a7dfd41ad832d79cdfdfce0291dac25" + "reference": "da21267abd9684c590a131a40173fb3c42eab722" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/masmerise/livewire-toaster/zipball/a47875b10a7dfd41ad832d79cdfdfce0291dac25", - "reference": "a47875b10a7dfd41ad832d79cdfdfce0291dac25", + "url": "https://api.github.com/repos/masmerise/livewire-toaster/zipball/da21267abd9684c590a131a40173fb3c42eab722", + "reference": "da21267abd9684c590a131a40173fb3c42eab722", "shasum": "" }, "require": { @@ -3017,9 +3065,9 @@ ], "support": { "issues": "https://github.com/masmerise/livewire-toaster/issues", - "source": "https://github.com/masmerise/livewire-toaster/tree/1.2.1" + "source": "https://github.com/masmerise/livewire-toaster/tree/1.3.0" }, - "time": "2023-07-03T19:45:56+00:00" + "time": "2023-08-05T18:22:07+00:00" }, { "name": "monolog/monolog", @@ -3287,21 +3335,21 @@ }, { "name": "nette/schema", - "version": "v1.2.3", + "version": "v1.2.4", "source": { "type": "git", "url": "https://github.com/nette/schema.git", - "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f" + "reference": "c9ff517a53903b3d4e29ec547fb20feecb05b8ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", - "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "url": "https://api.github.com/repos/nette/schema/zipball/c9ff517a53903b3d4e29ec547fb20feecb05b8ab", + "reference": "c9ff517a53903b3d4e29ec547fb20feecb05b8ab", "shasum": "" }, "require": { "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", - "php": ">=7.1 <8.3" + "php": "7.1 - 8.3" }, "require-dev": { "nette/tester": "^2.3 || ^2.4", @@ -3343,26 +3391,26 @@ ], "support": { "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.2.3" + "source": "https://github.com/nette/schema/tree/v1.2.4" }, - "time": "2022-10-13T01:24:26+00:00" + "time": "2023-08-05T18:56:25+00:00" }, { "name": "nette/utils", - "version": "v4.0.0", + "version": "v4.0.1", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e" + "reference": "9124157137da01b1f5a5a22d6486cb975f26db7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e", - "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e", + "url": "https://api.github.com/repos/nette/utils/zipball/9124157137da01b1f5a5a22d6486cb975f26db7e", + "reference": "9124157137da01b1f5a5a22d6486cb975f26db7e", "shasum": "" }, "require": { - "php": ">=8.0 <8.3" + "php": ">=8.0 <8.4" }, "conflict": { "nette/finder": "<3", @@ -3370,7 +3418,7 @@ }, "require-dev": { "jetbrains/phpstorm-attributes": "dev-master", - "nette/tester": "^2.4", + "nette/tester": "^2.5", "phpstan/phpstan": "^1.0", "tracy/tracy": "^2.9" }, @@ -3430,9 +3478,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.0" + "source": "https://github.com/nette/utils/tree/v4.0.1" }, - "time": "2023-02-02T10:41:53+00:00" + "time": "2023-07-30T15:42:21+00:00" }, { "name": "nikic/php-parser", @@ -4347,16 +4395,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.23.0", + "version": "1.23.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "a2b24135c35852b348894320d47b3902a94bc494" + "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a2b24135c35852b348894320d47b3902a94bc494", - "reference": "a2b24135c35852b348894320d47b3902a94bc494", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/846ae76eef31c6d7790fac9bc399ecee45160b26", + "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26", "shasum": "" }, "require": { @@ -4388,9 +4436,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.23.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.23.1" }, - "time": "2023-07-23T22:17:56+00:00" + "time": "2023-08-03T16:32:59+00:00" }, { "name": "pimple/pimple", @@ -5004,16 +5052,16 @@ }, { "name": "psy/psysh", - "version": "v0.11.19", + "version": "v0.11.20", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "1724ceff278daeeac5a006744633bacbb2dc4706" + "reference": "0fa27040553d1d280a67a4393194df5228afea5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/1724ceff278daeeac5a006744633bacbb2dc4706", - "reference": "1724ceff278daeeac5a006744633bacbb2dc4706", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/0fa27040553d1d280a67a4393194df5228afea5b", + "reference": "0fa27040553d1d280a67a4393194df5228afea5b", "shasum": "" }, "require": { @@ -5074,9 +5122,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.19" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.20" }, - "time": "2023-07-15T19:42:19+00:00" + "time": "2023-07-31T14:32:22+00:00" }, { "name": "ralouphie/getallheaders", @@ -5362,16 +5410,16 @@ }, { "name": "sentry/sentry", - "version": "3.20.1", + "version": "3.21.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "644ad9768c18139a80ac510090fad000d9ffd8a4" + "reference": "624aafc22b84b089ffa43b71fb01e0096505ec4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/644ad9768c18139a80ac510090fad000d9ffd8a4", - "reference": "644ad9768c18139a80ac510090fad000d9ffd8a4", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/624aafc22b84b089ffa43b71fb01e0096505ec4f", + "reference": "624aafc22b84b089ffa43b71fb01e0096505ec4f", "shasum": "" }, "require": { @@ -5415,11 +5463,6 @@ "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.13.x-dev" - } - }, "autoload": { "files": [ "src/functions.php" @@ -5451,7 +5494,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/3.20.1" + "source": "https://github.com/getsentry/sentry-php/tree/3.21.0" }, "funding": [ { @@ -5463,20 +5506,20 @@ "type": "custom" } ], - "time": "2023-06-26T11:01:40+00:00" + "time": "2023-07-31T15:31:24+00:00" }, { "name": "sentry/sentry-laravel", - "version": "3.6.1", + "version": "3.7.3", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-laravel.git", - "reference": "eb94a52b88794d0c108dc46ca1a680531c3a8bad" + "reference": "2aee4ad217be8ef04ffcde6e9f7dd17af5a3b0bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/eb94a52b88794d0c108dc46ca1a680531c3a8bad", - "reference": "eb94a52b88794d0c108dc46ca1a680531c3a8bad", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/2aee4ad217be8ef04ffcde6e9f7dd17af5a3b0bf", + "reference": "2aee4ad217be8ef04ffcde6e9f7dd17af5a3b0bf", "shasum": "" }, "require": { @@ -5484,7 +5527,7 @@ "nyholm/psr7": "^1.0", "php": "^7.2 | ^8.0", "sentry/sdk": "^3.4", - "sentry/sentry": "^3.20", + "sentry/sentry": "^3.20.1", "symfony/psr-http-message-bridge": "^1.0 | ^2.0" }, "require-dev": { @@ -5492,6 +5535,7 @@ "laravel/framework": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0", "mockery/mockery": "^1.3", "orchestra/testbench": "^4.7 | ^5.1 | ^6.0 | ^7.0 | ^8.0", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^8.4 | ^9.3" }, "type": "library", @@ -5541,7 +5585,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-laravel/issues", - "source": "https://github.com/getsentry/sentry-laravel/tree/3.6.1" + "source": "https://github.com/getsentry/sentry-laravel/tree/3.7.3" }, "funding": [ { @@ -5553,7 +5597,7 @@ "type": "custom" } ], - "time": "2023-07-04T10:30:42+00:00" + "time": "2023-08-03T10:10:23+00:00" }, { "name": "spatie/backtrace", @@ -5710,16 +5754,16 @@ }, { "name": "spatie/laravel-data", - "version": "3.7.0", + "version": "3.8.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-data.git", - "reference": "a975123d86e0133a361ac225d17acb3d11aa351f" + "reference": "0de2ecfc8fa98bcca6e2e041d22de8c74a19c45b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-data/zipball/a975123d86e0133a361ac225d17acb3d11aa351f", - "reference": "a975123d86e0133a361ac225d17acb3d11aa351f", + "url": "https://api.github.com/repos/spatie/laravel-data/zipball/0de2ecfc8fa98bcca6e2e041d22de8c74a19c45b", + "reference": "0de2ecfc8fa98bcca6e2e041d22de8c74a19c45b", "shasum": "" }, "require": { @@ -5781,7 +5825,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-data/issues", - "source": "https://github.com/spatie/laravel-data/tree/3.7.0" + "source": "https://github.com/spatie/laravel-data/tree/3.8.0" }, "funding": [ { @@ -5789,20 +5833,20 @@ "type": "github" } ], - "time": "2023-07-05T11:45:14+00:00" + "time": "2023-08-09T14:09:06+00:00" }, { "name": "spatie/laravel-package-tools", - "version": "1.15.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "efab1844b8826443135201c4443690f032c3d533" + "reference": "38fe533e93f86a1b2fb1000bf7df09c4748e6458" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/efab1844b8826443135201c4443690f032c3d533", - "reference": "efab1844b8826443135201c4443690f032c3d533", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/38fe533e93f86a1b2fb1000bf7df09c4748e6458", + "reference": "38fe533e93f86a1b2fb1000bf7df09c4748e6458", "shasum": "" }, "require": { @@ -5841,7 +5885,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.15.0" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.0" }, "funding": [ { @@ -5849,7 +5893,7 @@ "type": "github" } ], - "time": "2023-04-27T08:09:01+00:00" + "time": "2023-08-09T14:08:04+00:00" }, { "name": "spatie/laravel-ray", @@ -6202,16 +6246,16 @@ }, { "name": "symfony/console", - "version": "v6.3.0", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7" + "reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", - "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", + "url": "https://api.github.com/repos/symfony/console/zipball/aa5d64ad3f63f2e48964fc81ee45cb318a723898", + "reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898", "shasum": "" }, "require": { @@ -6272,7 +6316,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.0" + "source": "https://github.com/symfony/console/tree/v6.3.2" }, "funding": [ { @@ -6288,20 +6332,20 @@ "type": "tidelift" } ], - "time": "2023-05-29T12:49:39+00:00" + "time": "2023-07-19T20:17:28+00:00" }, { "name": "symfony/css-selector", - "version": "v6.3.0", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "88453e64cd86c5b60e8d2fb2c6f953bbc353ffbf" + "reference": "883d961421ab1709877c10ac99451632a3d6fa57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/88453e64cd86c5b60e8d2fb2c6f953bbc353ffbf", - "reference": "88453e64cd86c5b60e8d2fb2c6f953bbc353ffbf", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/883d961421ab1709877c10ac99451632a3d6fa57", + "reference": "883d961421ab1709877c10ac99451632a3d6fa57", "shasum": "" }, "require": { @@ -6337,7 +6381,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.3.0" + "source": "https://github.com/symfony/css-selector/tree/v6.3.2" }, "funding": [ { @@ -6353,7 +6397,7 @@ "type": "tidelift" } ], - "time": "2023-03-20T16:43:42+00:00" + "time": "2023-07-12T16:00:22+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6424,16 +6468,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.3.0", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "99d2d814a6351461af350ead4d963bd67451236f" + "reference": "85fd65ed295c4078367c784e8a5a6cee30348b7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/99d2d814a6351461af350ead4d963bd67451236f", - "reference": "99d2d814a6351461af350ead4d963bd67451236f", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/85fd65ed295c4078367c784e8a5a6cee30348b7a", + "reference": "85fd65ed295c4078367c784e8a5a6cee30348b7a", "shasum": "" }, "require": { @@ -6478,7 +6522,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.3.0" + "source": "https://github.com/symfony/error-handler/tree/v6.3.2" }, "funding": [ { @@ -6494,20 +6538,20 @@ "type": "tidelift" } ], - "time": "2023-05-10T12:03:13+00:00" + "time": "2023-07-16T17:05:46+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.3.0", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa" + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", - "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", "shasum": "" }, "require": { @@ -6558,7 +6602,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" }, "funding": [ { @@ -6574,7 +6618,7 @@ "type": "tidelift" } ], - "time": "2023-04-21T14:41:17+00:00" + "time": "2023-07-06T06:56:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -6654,16 +6698,16 @@ }, { "name": "symfony/finder", - "version": "v6.3.0", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2" + "reference": "9915db259f67d21eefee768c1abcf1cc61b1fc9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2", - "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "url": "https://api.github.com/repos/symfony/finder/zipball/9915db259f67d21eefee768c1abcf1cc61b1fc9e", + "reference": "9915db259f67d21eefee768c1abcf1cc61b1fc9e", "shasum": "" }, "require": { @@ -6698,7 +6742,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.3.0" + "source": "https://github.com/symfony/finder/tree/v6.3.3" }, "funding": [ { @@ -6714,20 +6758,20 @@ "type": "tidelift" } ], - "time": "2023-04-02T01:25:41+00:00" + "time": "2023-07-31T08:31:44+00:00" }, { "name": "symfony/http-client", - "version": "v6.3.1", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "1c828a06aef2f5eeba42026dfc532d4fc5406123" + "reference": "15f9f4bad62bfcbe48b5dedd866f04a08fc7ff00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/1c828a06aef2f5eeba42026dfc532d4fc5406123", - "reference": "1c828a06aef2f5eeba42026dfc532d4fc5406123", + "url": "https://api.github.com/repos/symfony/http-client/zipball/15f9f4bad62bfcbe48b5dedd866f04a08fc7ff00", + "reference": "15f9f4bad62bfcbe48b5dedd866f04a08fc7ff00", "shasum": "" }, "require": { @@ -6790,7 +6834,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.3.1" + "source": "https://github.com/symfony/http-client/tree/v6.3.2" }, "funding": [ { @@ -6806,7 +6850,7 @@ "type": "tidelift" } ], - "time": "2023-06-24T11:51:27+00:00" + "time": "2023-07-05T08:41:27+00:00" }, { "name": "symfony/http-client-contracts", @@ -6888,16 +6932,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.3.1", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e0ad0d153e1c20069250986cd9e9dd1ccebb0d66" + "reference": "43ed99d30f5f466ffa00bdac3f5f7aa9cd7617c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e0ad0d153e1c20069250986cd9e9dd1ccebb0d66", - "reference": "e0ad0d153e1c20069250986cd9e9dd1ccebb0d66", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/43ed99d30f5f466ffa00bdac3f5f7aa9cd7617c3", + "reference": "43ed99d30f5f466ffa00bdac3f5f7aa9cd7617c3", "shasum": "" }, "require": { @@ -6945,7 +6989,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.3.1" + "source": "https://github.com/symfony/http-foundation/tree/v6.3.2" }, "funding": [ { @@ -6961,20 +7005,20 @@ "type": "tidelift" } ], - "time": "2023-06-24T11:51:27+00:00" + "time": "2023-07-23T21:58:39+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.3.1", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "161e16fd2e35fb4881a43bc8b383dfd5be4ac374" + "reference": "d3b567f0addf695e10b0c6d57564a9bea2e058ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/161e16fd2e35fb4881a43bc8b383dfd5be4ac374", - "reference": "161e16fd2e35fb4881a43bc8b383dfd5be4ac374", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d3b567f0addf695e10b0c6d57564a9bea2e058ee", + "reference": "d3b567f0addf695e10b0c6d57564a9bea2e058ee", "shasum": "" }, "require": { @@ -7058,7 +7102,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.3.1" + "source": "https://github.com/symfony/http-kernel/tree/v6.3.3" }, "funding": [ { @@ -7074,7 +7118,7 @@ "type": "tidelift" } ], - "time": "2023-06-26T06:07:32+00:00" + "time": "2023-07-31T10:33:00+00:00" }, { "name": "symfony/mailer", @@ -7158,20 +7202,21 @@ }, { "name": "symfony/mime", - "version": "v6.3.0", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "7b5d2121858cd6efbed778abce9cfdd7ab1f62ad" + "reference": "9a0cbd52baa5ba5a5b1f0cacc59466f194730f98" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/7b5d2121858cd6efbed778abce9cfdd7ab1f62ad", - "reference": "7b5d2121858cd6efbed778abce9cfdd7ab1f62ad", + "url": "https://api.github.com/repos/symfony/mime/zipball/9a0cbd52baa5ba5a5b1f0cacc59466f194730f98", + "reference": "9a0cbd52baa5ba5a5b1f0cacc59466f194730f98", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -7180,7 +7225,7 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/mailer": "<5.4", - "symfony/serializer": "<6.2" + "symfony/serializer": "<6.2.13|>=6.3,<6.3.2" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", @@ -7189,7 +7234,7 @@ "symfony/dependency-injection": "^5.4|^6.0", "symfony/property-access": "^5.4|^6.0", "symfony/property-info": "^5.4|^6.0", - "symfony/serializer": "^6.2" + "symfony/serializer": "~6.2.13|^6.3.2" }, "type": "library", "autoload": { @@ -7221,7 +7266,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.3.0" + "source": "https://github.com/symfony/mime/tree/v6.3.3" }, "funding": [ { @@ -7237,7 +7282,7 @@ "type": "tidelift" } ], - "time": "2023-04-28T15:57:00+00:00" + "time": "2023-07-31T07:08:24+00:00" }, { "name": "symfony/options-resolver", @@ -8126,16 +8171,16 @@ }, { "name": "symfony/process", - "version": "v6.3.0", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628" + "reference": "c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628", - "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628", + "url": "https://api.github.com/repos/symfony/process/zipball/c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d", + "reference": "c5ce962db0d9b6e80247ca5eb9af6472bd4d7b5d", "shasum": "" }, "require": { @@ -8167,7 +8212,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.3.0" + "source": "https://github.com/symfony/process/tree/v6.3.2" }, "funding": [ { @@ -8183,7 +8228,7 @@ "type": "tidelift" } ], - "time": "2023-05-19T08:06:44+00:00" + "time": "2023-07-12T16:00:22+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -8276,20 +8321,21 @@ }, { "name": "symfony/routing", - "version": "v6.3.1", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "d37ad1779c38b8eb71996d17dc13030dcb7f9cf5" + "reference": "e7243039ab663822ff134fbc46099b5fdfa16f6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/d37ad1779c38b8eb71996d17dc13030dcb7f9cf5", - "reference": "d37ad1779c38b8eb71996d17dc13030dcb7f9cf5", + "url": "https://api.github.com/repos/symfony/routing/zipball/e7243039ab663822ff134fbc46099b5fdfa16f6a", + "reference": "e7243039ab663822ff134fbc46099b5fdfa16f6a", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "doctrine/annotations": "<1.12", @@ -8338,7 +8384,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.3.1" + "source": "https://github.com/symfony/routing/tree/v6.3.3" }, "funding": [ { @@ -8354,7 +8400,7 @@ "type": "tidelift" } ], - "time": "2023-06-05T15:30:22+00:00" + "time": "2023-07-31T07:08:24+00:00" }, { "name": "symfony/service-contracts", @@ -8502,16 +8548,16 @@ }, { "name": "symfony/string", - "version": "v6.3.0", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f" + "reference": "53d1a83225002635bca3482fcbf963001313fb68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f", + "url": "https://api.github.com/repos/symfony/string/zipball/53d1a83225002635bca3482fcbf963001313fb68", + "reference": "53d1a83225002635bca3482fcbf963001313fb68", "shasum": "" }, "require": { @@ -8568,7 +8614,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.0" + "source": "https://github.com/symfony/string/tree/v6.3.2" }, "funding": [ { @@ -8584,24 +8630,25 @@ "type": "tidelift" } ], - "time": "2023-03-21T21:06:29+00:00" + "time": "2023-07-05T08:41:27+00:00" }, { "name": "symfony/translation", - "version": "v6.3.0", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "f72b2cba8f79dd9d536f534f76874b58ad37876f" + "reference": "3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f72b2cba8f79dd9d536f534f76874b58ad37876f", - "reference": "f72b2cba8f79dd9d536f534f76874b58ad37876f", + "url": "https://api.github.com/repos/symfony/translation/zipball/3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd", + "reference": "3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/translation-contracts": "^2.5|^3.0" }, @@ -8662,7 +8709,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.3.0" + "source": "https://github.com/symfony/translation/tree/v6.3.3" }, "funding": [ { @@ -8678,7 +8725,7 @@ "type": "tidelift" } ], - "time": "2023-05-19T12:46:45+00:00" + "time": "2023-07-31T07:08:24+00:00" }, { "name": "symfony/translation-contracts", @@ -8834,20 +8881,21 @@ }, { "name": "symfony/var-dumper", - "version": "v6.3.1", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "c81268d6960ddb47af17391a27d222bd58cf0515" + "reference": "77fb4f2927f6991a9843633925d111147449ee7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c81268d6960ddb47af17391a27d222bd58cf0515", - "reference": "c81268d6960ddb47af17391a27d222bd58cf0515", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/77fb4f2927f6991a9843633925d111147449ee7a", + "reference": "77fb4f2927f6991a9843633925d111147449ee7a", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -8856,6 +8904,7 @@ "require-dev": { "ext-iconv": "*", "symfony/console": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", "symfony/process": "^5.4|^6.0", "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" @@ -8896,7 +8945,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.3.1" + "source": "https://github.com/symfony/var-dumper/tree/v6.3.3" }, "funding": [ { @@ -8912,24 +8961,25 @@ "type": "tidelift" } ], - "time": "2023-06-21T12:08:28+00:00" + "time": "2023-07-31T07:08:24+00:00" }, { "name": "symfony/yaml", - "version": "v6.3.0", + "version": "v6.3.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927" + "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a9a8337aa641ef2aa39c3e028f9107ec391e5927", - "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e23292e8c07c85b971b44c1c4b87af52133e2add", + "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -8967,7 +9017,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.3.0" + "source": "https://github.com/symfony/yaml/tree/v6.3.3" }, "funding": [ { @@ -8983,7 +9033,7 @@ "type": "tidelift" } ], - "time": "2023-04-28T13:28:14+00:00" + "time": "2023-07-31T07:08:24+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -9524,16 +9574,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v7.2.3", + "version": "v7.2.5", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "ec6713d48856b7e8af64b2f94b084fb861bcc71b" + "reference": "4d7ad5b6564f63baa1b948ecad05439f22880942" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/ec6713d48856b7e8af64b2f94b084fb861bcc71b", - "reference": "ec6713d48856b7e8af64b2f94b084fb861bcc71b", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/4d7ad5b6564f63baa1b948ecad05439f22880942", + "reference": "4d7ad5b6564f63baa1b948ecad05439f22880942", "shasum": "" }, "require": { @@ -9544,13 +9594,13 @@ "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1", "jean85/pretty-package-versions": "^2.0.5", "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "phpunit/php-code-coverage": "^10.1.2", + "phpunit/php-code-coverage": "^10.1.3", "phpunit/php-file-iterator": "^4.0.2", "phpunit/php-timer": "^6.0", - "phpunit/phpunit": "^10.2.6", + "phpunit/phpunit": "^10.3.1", "sebastian/environment": "^6.0.1", - "symfony/console": "^6.3.0", - "symfony/process": "^6.3.0" + "symfony/console": "^6.3.2", + "symfony/process": "^6.3.2" }, "require-dev": { "doctrine/coding-standard": "^12.0.0", @@ -9603,7 +9653,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.2.3" + "source": "https://github.com/paratestphp/paratest/tree/v7.2.5" }, "funding": [ { @@ -9615,7 +9665,7 @@ "type": "paypal" } ], - "time": "2023-07-20T10:18:35+00:00" + "time": "2023-08-08T13:23:59+00:00" }, { "name": "fakerphp/faker", @@ -9870,16 +9920,16 @@ }, { "name": "laravel/dusk", - "version": "v7.9.1", + "version": "v7.9.3", "source": { "type": "git", "url": "https://github.com/laravel/dusk.git", - "reference": "c7261854fa3be500c2e331600eb1b265052690be" + "reference": "8d7ce583fb362472558cc1852adccfcd86cf87e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/dusk/zipball/c7261854fa3be500c2e331600eb1b265052690be", - "reference": "c7261854fa3be500c2e331600eb1b265052690be", + "url": "https://api.github.com/repos/laravel/dusk/zipball/8d7ce583fb362472558cc1852adccfcd86cf87e4", + "reference": "8d7ce583fb362472558cc1852adccfcd86cf87e4", "shasum": "" }, "require": { @@ -9940,22 +9990,22 @@ ], "support": { "issues": "https://github.com/laravel/dusk/issues", - "source": "https://github.com/laravel/dusk/tree/v7.9.1" + "source": "https://github.com/laravel/dusk/tree/v7.9.3" }, - "time": "2023-07-27T02:09:52+00:00" + "time": "2023-08-03T16:00:26+00:00" }, { "name": "laravel/pint", - "version": "v1.10.5", + "version": "v1.10.6", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "a458fb057bfa2f5a09888a8aa349610be807b0c3" + "reference": "d1915b6ecc6406c00472c6b9ae75b46aa153bbb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/a458fb057bfa2f5a09888a8aa349610be807b0c3", - "reference": "a458fb057bfa2f5a09888a8aa349610be807b0c3", + "url": "https://api.github.com/repos/laravel/pint/zipball/d1915b6ecc6406c00472c6b9ae75b46aa153bbb2", + "reference": "d1915b6ecc6406c00472c6b9ae75b46aa153bbb2", "shasum": "" }, "require": { @@ -10008,35 +10058,35 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2023-07-14T10:26:01+00:00" + "time": "2023-08-08T15:17:16+00:00" }, { "name": "mockery/mockery", - "version": "1.6.4", + "version": "1.6.6", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "d1413755e26fe56a63455f7753221c86cbb88f66" + "reference": "b8e0bb7d8c604046539c1115994632c74dcb361e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/d1413755e26fe56a63455f7753221c86cbb88f66", - "reference": "d1413755e26fe56a63455f7753221c86cbb88f66", + "url": "https://api.github.com/repos/mockery/mockery/zipball/b8e0bb7d8c604046539c1115994632c74dcb361e", + "reference": "b8e0bb7d8c604046539c1115994632c74dcb361e", "shasum": "" }, "require": { "hamcrest/hamcrest-php": "^2.0.1", "lib-pcre": ">=7.0", - "php": ">=7.4,<8.3" + "php": ">=7.3" }, "conflict": { "phpunit/phpunit": "<8.0" }, "require-dev": { - "phpunit/phpunit": "^8.5 || ^9.3", + "phpunit/phpunit": "^8.5 || ^9.6.10", "psalm/plugin-phpunit": "^0.18.4", "symplify/easy-coding-standard": "^11.5.0", - "vimeo/psalm": "^5.13.1" + "vimeo/psalm": "^4.30" }, "type": "library", "autoload": { @@ -10093,7 +10143,7 @@ "security": "https://github.com/mockery/mockery/security/advisories", "source": "https://github.com/mockery/mockery" }, - "time": "2023-07-19T15:51:02+00:00" + "time": "2023-08-09T00:03:52+00:00" }, { "name": "myclabs/deep-copy", @@ -10156,38 +10206,35 @@ }, { "name": "nunomaduro/collision", - "version": "v7.7.0", + "version": "v7.8.1", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "69a07197d055456d29911116fca3bc2c985f524b" + "reference": "61553ad3260845d7e3e49121b7074619233d361b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/69a07197d055456d29911116fca3bc2c985f524b", - "reference": "69a07197d055456d29911116fca3bc2c985f524b", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/61553ad3260845d7e3e49121b7074619233d361b", + "reference": "61553ad3260845d7e3e49121b7074619233d361b", "shasum": "" }, "require": { - "filp/whoops": "^2.15.2", + "filp/whoops": "^2.15.3", "nunomaduro/termwind": "^1.15.1", "php": "^8.1.0", - "symfony/console": "^6.3.0" - }, - "conflict": { - "phpunit/phpunit": "<10.1.2" + "symfony/console": "^6.3.2" }, "require-dev": { - "brianium/paratest": "^7.2.2", - "laravel/framework": "^10.14.1", - "laravel/pint": "^1.10.3", - "laravel/sail": "^1.23.0", + "brianium/paratest": "^7.2.4", + "laravel/framework": "^10.17.1", + "laravel/pint": "^1.10.5", + "laravel/sail": "^1.23.1", "laravel/sanctum": "^3.2.5", "laravel/tinker": "^2.8.1", - "nunomaduro/larastan": "^2.6.3", - "orchestra/testbench-core": "^8.5.8", - "pestphp/pest": "^2.8.1", - "phpunit/phpunit": "^10.2.2", + "nunomaduro/larastan": "^2.6.4", + "orchestra/testbench-core": "^8.5.9", + "pestphp/pest": "^2.12.1", + "phpunit/phpunit": "^10.3.1", "sebastian/environment": "^6.0.1", "spatie/laravel-ignition": "^2.2.0" }, @@ -10248,39 +10295,39 @@ "type": "patreon" } ], - "time": "2023-06-29T09:10:16+00:00" + "time": "2023-08-07T08:03:21+00:00" }, { "name": "pestphp/pest", - "version": "v2.9.5", + "version": "v2.13.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "be41181b435ce3d99d01be0d6c1e2602f153b82b" + "reference": "47f2ae32c14cd3f15520f5a12a3c36fdec25a2ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/be41181b435ce3d99d01be0d6c1e2602f153b82b", - "reference": "be41181b435ce3d99d01be0d6c1e2602f153b82b", + "url": "https://api.github.com/repos/pestphp/pest/zipball/47f2ae32c14cd3f15520f5a12a3c36fdec25a2ee", + "reference": "47f2ae32c14cd3f15520f5a12a3c36fdec25a2ee", "shasum": "" }, "require": { - "brianium/paratest": "^7.2.3", - "nunomaduro/collision": "^7.7.0", + "brianium/paratest": "^7.2.5", + "nunomaduro/collision": "^7.8.1", "nunomaduro/termwind": "^1.15.1", "pestphp/pest-plugin": "^2.0.1", "pestphp/pest-plugin-arch": "^2.2.3", "php": "^8.1.0", - "phpunit/phpunit": "^10.2.6" + "phpunit/phpunit": "^10.3.1" }, "conflict": { - "phpunit/phpunit": ">10.2.6", + "phpunit/phpunit": ">10.3.1", "webmozart/assert": "<1.11.0" }, "require-dev": { - "pestphp/pest-dev-tools": "^2.12.0", + "pestphp/pest-dev-tools": "^2.14.0", "pestphp/pest-plugin-type-coverage": "^2.0.0", - "symfony/process": "^6.3.0" + "symfony/process": "^6.3.2" }, "bin": [ "bin/pest" @@ -10302,6 +10349,7 @@ "Pest\\Plugins\\Profile", "Pest\\Plugins\\Retry", "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", "Pest\\Plugins\\Version", "Pest\\Plugins\\Parallel" ] @@ -10337,7 +10385,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v2.9.5" + "source": "https://github.com/pestphp/pest/tree/v2.13.0" }, "funding": [ { @@ -10349,7 +10397,7 @@ "type": "github" } ], - "time": "2023-07-24T18:13:17+00:00" + "time": "2023-08-09T11:14:39+00:00" }, { "name": "pestphp/pest-plugin", @@ -10720,16 +10768,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.26", + "version": "1.10.28", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "5d660cbb7e1b89253a47147ae44044f49832351f" + "reference": "e4545b55904ebef470423d3ddddb74fa7325497a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5d660cbb7e1b89253a47147ae44044f49832351f", - "reference": "5d660cbb7e1b89253a47147ae44044f49832351f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e4545b55904ebef470423d3ddddb74fa7325497a", + "reference": "e4545b55904ebef470423d3ddddb74fa7325497a", "shasum": "" }, "require": { @@ -10778,7 +10826,7 @@ "type": "tidelift" } ], - "time": "2023-07-19T12:44:37+00:00" + "time": "2023-08-08T12:33:42+00:00" }, { "name": "phpunit/php-code-coverage", @@ -11102,16 +11150,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.2.6", + "version": "10.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd" + "reference": "d442ce7c4104d5683c12e67e4dcb5058159e9804" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c17815c129f133f3019cc18e8d0c8622e6d9bcd", - "reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d442ce7c4104d5683c12e67e4dcb5058159e9804", + "reference": "d442ce7c4104d5683c12e67e4dcb5058159e9804", "shasum": "" }, "require": { @@ -11136,7 +11184,7 @@ "sebastian/diff": "^5.0", "sebastian/environment": "^6.0", "sebastian/exporter": "^5.0", - "sebastian/global-state": "^6.0", + "sebastian/global-state": "^6.0.1", "sebastian/object-enumerator": "^5.0", "sebastian/recursion-context": "^5.0", "sebastian/type": "^4.0", @@ -11151,7 +11199,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.2-dev" + "dev-main": "10.3-dev" } }, "autoload": { @@ -11183,7 +11231,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.6" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.1" }, "funding": [ { @@ -11199,7 +11247,7 @@ "type": "tidelift" } ], - "time": "2023-07-17T12:08:28+00:00" + "time": "2023-08-04T06:48:08+00:00" }, { "name": "sebastian/cli-parser", @@ -12404,16 +12452,16 @@ }, { "name": "ta-tikoma/phpunit-architecture-test", - "version": "0.7.3", + "version": "0.7.4", "source": { "type": "git", "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", - "reference": "90b2e1d53b2c09b6371f84476699b69b36e378fd" + "reference": "abe1f8a5f4635e7cbe0a8a37d6b8d20c687af0f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/90b2e1d53b2c09b6371f84476699b69b36e378fd", - "reference": "90b2e1d53b2c09b6371f84476699b69b36e378fd", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/abe1f8a5f4635e7cbe0a8a37d6b8d20c687af0f2", + "reference": "abe1f8a5f4635e7cbe0a8a37d6b8d20c687af0f2", "shasum": "" }, "require": { @@ -12457,9 +12505,9 @@ ], "support": { "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", - "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.7.3" + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.7.4" }, - "time": "2023-04-19T08:46:06+00:00" + "time": "2023-08-03T06:50:14+00:00" }, { "name": "theseer/tokenizer", diff --git a/database/migrations/2023_08_08_150103_create_scheduled_database_backups_table.php b/database/migrations/2023_08_08_150103_create_scheduled_database_backups_table.php index c0f6aecfd..8eb76cd72 100644 --- a/database/migrations/2023_08_08_150103_create_scheduled_database_backups_table.php +++ b/database/migrations/2023_08_08_150103_create_scheduled_database_backups_table.php @@ -11,9 +11,9 @@ public function up(): void $table->id(); $table->string('uuid')->unique(); $table->boolean('enabled')->default(true); - $table->boolean('keep_locally')->default(false); $table->string('save_s3')->default(true); $table->string('frequency'); + $table->integer('number_of_backups_locally')->default(7); $table->morphs('database'); $table->foreignId('team_id'); $table->timestamps(); diff --git a/database/migrations/2023_08_10_113306_create_scheduled_database_backup_executions_table.php b/database/migrations/2023_08_10_113306_create_scheduled_database_backup_executions_table.php new file mode 100644 index 000000000..96d1f3d47 --- /dev/null +++ b/database/migrations/2023_08_10_113306_create_scheduled_database_backup_executions_table.php @@ -0,0 +1,26 @@ +id(); + $table->string('uuid')->unique(); + $table->enum('status', ['success', 'failed', 'running'])->default('running'); + $table->longText('message')->nullable(); + $table->text('size')->nullable(); + $table->text('filename')->nullable(); + $table->foreignId('scheduled_database_backup_id'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('scheduled_database_backup_executions'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index c76beb63f..135b749bc 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,7 +32,8 @@ public function run(): void LocalPersistentVolumeSeeder::class, S3StorageSeeder::class, StandalonePostgresqlSeeder::class, - ScheduledDatabaseBackupSeeder::class + ScheduledDatabaseBackupSeeder::class, + ScheduledDatabaseBackupExecutionSeeder::class, ]); } } diff --git a/database/seeders/ScheduledDatabaseBackupExecutionSeeder.php b/database/seeders/ScheduledDatabaseBackupExecutionSeeder.php new file mode 100644 index 000000000..e4b5780c9 --- /dev/null +++ b/database/seeders/ScheduledDatabaseBackupExecutionSeeder.php @@ -0,0 +1,28 @@ + 'success', + 'message' => 'Backup created successfully.', + 'size' => '10243467789556', + 'scheduled_database_backup_id' => 1, + ]); + ScheduledDatabaseBackupExecution::create([ + 'status' => 'failed', + 'message' => 'Backup failed.', + 'size' => '10243456', + 'scheduled_database_backup_id' => 1, + ]); + } +} diff --git a/database/seeders/ScheduledDatabaseBackupSeeder.php b/database/seeders/ScheduledDatabaseBackupSeeder.php index dc4c2bd5d..a6fa6d820 100644 --- a/database/seeders/ScheduledDatabaseBackupSeeder.php +++ b/database/seeders/ScheduledDatabaseBackupSeeder.php @@ -15,7 +15,7 @@ public function run(): void ScheduledDatabaseBackup::create([ 'enabled' => true, 'frequency' => '* * * * *', - 'keep_locally' => true, + 'number_of_backups_locally' => 2, 'database_id' => 1, 'database_type' => 'App\Models\StandalonePostgresql', 'team_id' => 0, diff --git a/resources/views/components/databases/navbar.blade.php b/resources/views/components/databases/navbar.blade.php index 6d2cfd7fb..0ea49ede0 100644 --- a/resources/views/components/databases/navbar.blade.php +++ b/resources/views/components/databases/navbar.blade.php @@ -3,8 +3,8 @@ href="{{ route('project.database.configuration', $parameters) }}"> - + {{-- --}} diff --git a/resources/views/livewire/project/database/backup-edit.blade.php b/resources/views/livewire/project/database/backup-edit.blade.php new file mode 100644 index 000000000..f66a9a763 --- /dev/null +++ b/resources/views/livewire/project/database/backup-edit.blade.php @@ -0,0 +1,16 @@ +
+
+

Scheduled Backup

+ + Save + +
+
+ + +
+
+ + +
+
diff --git a/resources/views/livewire/project/database/backup-execution.blade.php b/resources/views/livewire/project/database/backup-execution.blade.php new file mode 100644 index 000000000..c8d73525e --- /dev/null +++ b/resources/views/livewire/project/database/backup-execution.blade.php @@ -0,0 +1,7 @@ +
+
+ {{-- @if(data_get($execution,'status') !== 'failed')--}} + {{-- Download--}} + {{-- @endif--}} + Delete +
diff --git a/resources/views/livewire/project/database/backup-executions.blade.php b/resources/views/livewire/project/database/backup-executions.blade.php new file mode 100644 index 000000000..930ea4831 --- /dev/null +++ b/resources/views/livewire/project/database/backup-executions.blade.php @@ -0,0 +1,22 @@ +
+ @forelse($executions as $execution) +
data_get($execution,'status') === 'success', + 'border-red-500' => data_get($execution,'status') === 'failed', + ])> +
Status: {{data_get($execution,'status')}}
+ @if(data_get($execution,'message')) +
Message: {{data_get($execution,'message')}}
+ @endif +
Size: {{data_get($execution,'size')}} B / {{round((int)data_get($execution,'size') / 1024,2)}} + kB / {{round((int)data_get($execution,'size')/1024/1024,2)}} MB +
+
Location: {{data_get($execution,'filename')}}
+ + + @empty +
No logs found.
+ @endforelse + +
diff --git a/resources/views/livewire/project/database/create-scheduled-backup.blade.php b/resources/views/livewire/project/database/create-scheduled-backup.blade.php index cdbdcc766..6a4ccc351 100644 --- a/resources/views/livewire/project/database/create-scheduled-backup.blade.php +++ b/resources/views/livewire/project/database/create-scheduled-backup.blade.php @@ -1,7 +1,6 @@