2023-08-10 13:52:54 +00:00
< ? php
2023-12-07 18:06:32 +00:00
namespace App\Livewire\Project\Database ;
2023-08-10 13:52:54 +00:00
2024-10-22 10:29:48 +00:00
use App\Models\InstanceSettings ;
2024-05-24 15:20:20 +00:00
use App\Models\ScheduledDatabaseBackup ;
2024-09-23 17:51:31 +00:00
use Illuminate\Support\Facades\Auth ;
use Illuminate\Support\Facades\Hash ;
2023-08-10 13:52:54 +00:00
use Livewire\Component ;
2023-11-07 11:11:47 +00:00
use Spatie\Url\Url ;
2023-08-10 13:52:54 +00:00
class BackupEdit extends Component
{
2024-05-24 15:20:20 +00:00
public ? ScheduledDatabaseBackup $backup ;
2024-06-10 20:43:34 +00:00
2023-08-11 14:13:53 +00:00
public $s3s ;
2024-06-10 20:43:34 +00:00
2024-09-02 17:27:21 +00:00
public bool $delete_associated_backups_locally = false ;
2024-09-23 17:51:31 +00:00
2024-09-02 17:27:21 +00:00
public bool $delete_associated_backups_s3 = false ;
2024-09-23 17:51:31 +00:00
2024-09-02 17:27:21 +00:00
public bool $delete_associated_backups_sftp = false ;
2024-08-31 16:29:19 +00:00
2023-10-10 11:10:43 +00:00
public ? string $status = null ;
2024-06-10 20:43:34 +00:00
2023-08-10 14:28:29 +00:00
public array $parameters ;
2023-08-10 13:52:54 +00:00
protected $rules = [
'backup.enabled' => 'required|boolean' ,
'backup.frequency' => 'required|string' ,
'backup.number_of_backups_locally' => 'required|integer|min:1' ,
2023-08-10 15:55:03 +00:00
'backup.save_s3' => 'required|boolean' ,
2023-08-11 14:13:53 +00:00
'backup.s3_storage_id' => 'nullable|integer' ,
2023-10-13 13:45:24 +00:00
'backup.databases_to_backup' => 'nullable' ,
2024-10-03 10:39:45 +00:00
'backup.dump_all' => 'required|boolean' ,
2023-08-10 13:52:54 +00:00
];
2024-06-10 20:43:34 +00:00
2023-08-10 13:52:54 +00:00
protected $validationAttributes = [
'backup.enabled' => 'Enabled' ,
'backup.frequency' => 'Frequency' ,
'backup.number_of_backups_locally' => 'Number of Backups Locally' ,
2023-08-10 15:55:03 +00:00
'backup.save_s3' => 'Save to S3' ,
2023-08-11 14:13:53 +00:00
'backup.s3_storage_id' => 'S3 Storage' ,
2023-10-13 13:45:24 +00:00
'backup.databases_to_backup' => 'Databases to Backup' ,
2024-10-03 10:39:45 +00:00
'backup.dump_all' => 'Backup All Databases' ,
2023-08-11 14:13:53 +00:00
];
2024-06-10 20:43:34 +00:00
2023-08-11 14:13:53 +00:00
protected $messages = [
'backup.s3_storage_id' => 'Select a S3 Storage' ,
2023-08-10 13:52:54 +00:00
];
2023-08-10 14:28:29 +00:00
public function mount ()
{
$this -> parameters = get_route_parameters ();
2024-05-17 11:43:21 +00:00
if ( is_null ( data_get ( $this -> backup , 's3_storage_id' ))) {
2024-05-24 15:20:20 +00:00
data_set ( $this -> backup , 's3_storage_id' , 'default' );
2023-08-11 14:13:53 +00:00
}
2023-08-10 14:28:29 +00:00
}
2024-08-31 16:29:19 +00:00
public function delete ( $password )
2023-08-10 14:25:59 +00:00
{
2024-10-24 14:20:01 +00:00
if ( ! data_get ( InstanceSettings :: get (), 'disable_two_step_confirmation' )) {
2024-10-22 10:29:48 +00:00
if ( ! Hash :: check ( $password , Auth :: user () -> password )) {
$this -> addError ( 'password' , 'The provided password is incorrect.' );
2024-09-23 17:51:31 +00:00
2024-10-22 10:29:48 +00:00
return ;
}
2024-08-31 16:29:19 +00:00
}
2024-03-21 11:44:32 +00:00
try {
2024-09-02 17:27:21 +00:00
if ( $this -> delete_associated_backups_locally ) {
$this -> deleteAssociatedBackupsLocally ();
}
if ( $this -> delete_associated_backups_s3 ) {
$this -> deleteAssociatedBackupsS3 ();
2024-08-31 16:29:19 +00:00
}
2024-03-21 11:44:32 +00:00
$this -> backup -> delete ();
2024-08-31 16:29:19 +00:00
2024-10-28 13:56:13 +00:00
if ( $this -> backup -> database -> getMorphClass () === \App\Models\ServiceDatabase :: class ) {
2024-03-21 11:44:32 +00:00
$previousUrl = url () -> previous ();
$url = Url :: fromString ( $previousUrl );
$url = $url -> withoutQueryParameter ( 'selectedBackupId' );
$url = $url -> withFragment ( 'backups' );
2024-09-23 17:51:31 +00:00
$url = $url -> getPath () . " # { $url -> getFragment () } " ;
2024-06-10 20:43:34 +00:00
2024-03-21 11:44:32 +00:00
return redirect ( $url );
} else {
return redirect () -> route ( 'project.database.backup.index' , $this -> parameters );
}
} catch ( \Throwable $e ) {
return handleError ( $e , $this );
2023-11-07 11:11:47 +00:00
}
2023-08-10 14:25:59 +00:00
}
2023-08-10 13:52:54 +00:00
public function instantSave ()
{
2023-08-11 14:13:53 +00:00
try {
$this -> custom_validate ();
$this -> backup -> save ();
$this -> backup -> refresh ();
2024-03-21 11:44:32 +00:00
$this -> dispatch ( 'success' , 'Backup updated successfully.' );
2023-09-11 15:36:30 +00:00
} catch ( \Throwable $e ) {
2023-12-07 18:06:32 +00:00
$this -> dispatch ( 'error' , $e -> getMessage ());
2023-08-11 14:13:53 +00:00
}
2023-08-10 13:52:54 +00:00
}
2023-08-11 14:13:53 +00:00
private function custom_validate ()
2023-08-10 13:52:54 +00:00
{
2024-06-10 20:43:34 +00:00
if ( ! is_numeric ( $this -> backup -> s3_storage_id )) {
2023-08-11 18:48:52 +00:00
$this -> backup -> s3_storage_id = null ;
}
2023-08-10 13:52:54 +00:00
$isValid = validate_cron_expression ( $this -> backup -> frequency );
2024-06-10 20:43:34 +00:00
if ( ! $isValid ) {
2023-08-11 14:13:53 +00:00
throw new \Exception ( 'Invalid Cron / Human expression' );
2023-08-10 13:52:54 +00:00
}
$this -> validate ();
2023-08-11 14:13:53 +00:00
}
public function submit ()
{
try {
$this -> custom_validate ();
2024-10-31 14:23:19 +00:00
if ( $this -> backup -> databases_to_backup === '' || $this -> backup -> databases_to_backup === null ) {
2023-10-13 13:45:24 +00:00
$this -> backup -> databases_to_backup = null ;
}
2023-08-11 14:13:53 +00:00
$this -> backup -> save ();
$this -> backup -> refresh ();
2023-12-07 18:06:32 +00:00
$this -> dispatch ( 'success' , 'Backup updated successfully' );
2023-09-11 15:36:30 +00:00
} catch ( \Throwable $e ) {
2023-12-07 18:06:32 +00:00
$this -> dispatch ( 'error' , $e -> getMessage ());
2023-08-11 14:13:53 +00:00
}
2023-08-10 13:52:54 +00:00
}
2024-08-31 16:29:19 +00:00
2024-09-02 17:27:21 +00:00
public function deleteAssociatedBackupsLocally ()
2024-08-31 16:29:19 +00:00
{
$executions = $this -> backup -> executions ;
2024-08-31 16:38:57 +00:00
$backupFolder = null ;
2024-08-31 16:29:19 +00:00
foreach ( $executions as $execution ) {
2024-10-28 13:56:13 +00:00
if ( $this -> backup -> database -> getMorphClass () === \App\Models\ServiceDatabase :: class ) {
2024-08-31 16:38:57 +00:00
$server = $this -> backup -> database -> service -> destination -> server ;
2024-08-31 16:29:19 +00:00
} else {
2024-08-31 16:38:57 +00:00
$server = $this -> backup -> database -> destination -> server ;
2024-08-31 16:29:19 +00:00
}
2024-09-23 17:51:31 +00:00
if ( ! $backupFolder ) {
2024-08-31 16:38:57 +00:00
$backupFolder = dirname ( $execution -> filename );
}
2024-09-23 17:51:31 +00:00
2024-08-31 16:38:57 +00:00
delete_backup_locally ( $execution -> filename , $server );
2024-08-31 16:29:19 +00:00
$execution -> delete ();
}
2024-08-31 16:38:57 +00:00
if ( $backupFolder ) {
$this -> deleteEmptyBackupFolder ( $backupFolder , $server );
}
}
2024-09-02 17:27:21 +00:00
public function deleteAssociatedBackupsS3 ()
{
//Add function to delete backups from S3
}
public function deleteAssociatedBackupsSftp ()
{
//Add function to delete backups from SFTP
}
2024-08-31 16:38:57 +00:00
private function deleteEmptyBackupFolder ( $folderPath , $server )
{
$checkEmpty = instant_remote_process ([ " [ -z \" $ (ls -A ' $folderPath ') \" ] && echo 'empty' || echo 'not empty' " ], $server );
2024-09-23 17:51:31 +00:00
2024-08-31 16:38:57 +00:00
if ( trim ( $checkEmpty ) === 'empty' ) {
instant_remote_process ([ " rmdir ' $folderPath ' " ], $server );
2024-09-23 17:51:31 +00:00
2024-08-31 16:38:57 +00:00
$parentFolder = dirname ( $folderPath );
$checkParentEmpty = instant_remote_process ([ " [ -z \" $ (ls -A ' $parentFolder ') \" ] && echo 'empty' || echo 'not empty' " ], $server );
2024-09-23 17:51:31 +00:00
2024-08-31 16:38:57 +00:00
if ( trim ( $checkParentEmpty ) === 'empty' ) {
instant_remote_process ([ " rmdir ' $parentFolder ' " ], $server );
}
}
2024-08-31 16:29:19 +00:00
}
public function render ()
{
return view ( 'livewire.project.database.backup-edit' , [
'checkboxes' => [
2024-09-27 15:29:36 +00:00
[ 'id' => 'delete_associated_backups_locally' , 'label' => __ ( 'database.delete_backups_locally' )],
2024-09-02 17:27:21 +00:00
// ['id' => 'delete_associated_backups_s3', 'label' => 'All backups associated with this backup job from this database will be permanently deleted from the selected S3 Storage.']
// ['id' => 'delete_associated_backups_sftp', 'label' => 'All backups associated with this backup job from this database will be permanently deleted from the selected SFTP Storage.']
2024-09-23 17:51:31 +00:00
],
2024-08-31 16:29:19 +00:00
]);
}
2023-08-10 13:52:54 +00:00
}