Skip to content

Commit a5ccb56

Browse files
Refactor code structure for improved readability and maintainability
1 parent 2845e82 commit a5ccb56

File tree

6 files changed

+53
-193
lines changed

6 files changed

+53
-193
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,8 @@ php artisan queue:work >> /dev/null 2>&1
141141
```
142142

143143
## Restore Backup
144-
Isi dari file backup adalah dump sql database dan file di dalam folder storage/app/public
145-
Restore dilakukan manual. Setelah selesai jalankan command:
144+
Untuk melakukan restore jalankan command:
146145
```bash
147-
php artisan simpede:cache
146+
php artisan simpede:restore
148147
```
149148

app/Console/Commands/Install.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ public function handle()
6464
[
6565
'nama' => 'Template Kerangka Acuan Kerja',
6666
'jenis' => 'kak',
67-
'file' => 'ReAdPXzRYWqgpho3W0mX4U3rxg3UfZ3F4MmKlxsP.docx',
67+
'file' => 'kli5jt06bmTBJnLoQiQQN5md2iujNW317bGeQ46E.docx',
6868
],
6969
[
7070
'nama' => 'Template SPJ',
7171
'jenis' => 'spj',
72-
'file' => 'd2z8X186YFymCM29dPa84LH7rTrqljrmfhmyc7C4.docx',
72+
'file' => '8UaqlK0dwmtx64Ih8scHARLKk9yXEtAsMsDhAyqT.docx',
7373
],
7474
[
7575
'nama' => 'Template SK Petugas',
@@ -184,7 +184,7 @@ public function handle()
184184
[
185185
'nama' => 'Template Tanda Terima Pulsa',
186186
'jenis' => 'pulsa',
187-
'file' => 'uzvdQmXrt7hesC2ULRZVQhmcQEkTJdIwIJvKALmX.docx',
187+
'file' => 'AuX5vZ1DGxJvIJksXLGfXO35fBRFCR9BdAI1bZH5.docx',
188188
],
189189
];
190190

app/Console/Commands/SimpedeRestore.php

Lines changed: 48 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ class SimpedeRestore extends Command
2121
{--disk= : The disk to restore from (local, google)}
2222
{--backup= : Specific backup file to restore (optional)}
2323
{--connection= : Database connection to restore to}
24-
{--reset : Drop all tables before restoring}
25-
{--database-only : Restore only database}
26-
{--files-only : Restore only files}
2724
{--list : List available backups}
25+
{--only-db : Restoring database only}
26+
{--only-files : Restoring files only}
2827
{--force : Skip confirmation prompts}';
2928

3029
/**
@@ -46,7 +45,6 @@ public function handle()
4645
$this->info('🔄 Complete Backup Restore Tool');
4746
$this->line('');
4847

49-
// Safety warnings
5048
if (! $this->option('force')) {
5149
$this->warn('⚠️ WARNING: This will restore your database AND files from backup!');
5250
$this->warn('⚠️ This operation will overwrite your current data and files.');
@@ -61,13 +59,10 @@ public function handle()
6159

6260
$disk = $this->option('disk') ?? config('backup.backup.destination.disks')[0];
6361
$backup = $this->option('backup');
64-
$databaseOnly = $this->option('database-only');
65-
$filesOnly = $this->option('files-only');
66-
67-
$tempDir = null; // <-- Tambahan variabel tempDir global handle
68-
62+
$tempDir = null;
63+
$success = true;
64+
$this->call('maintenance', ['action' => 'start']);
6965
try {
70-
// Find the backup file
7166
$backupFile = $this->findBackupFile($disk, $backup);
7267
if (! $backupFile) {
7368
$this->error('❌ Backup file not found!');
@@ -78,69 +73,66 @@ public function handle()
7873
$this->info('📁 Using backup: '.basename($backupFile));
7974
$this->line('');
8075

81-
$success = true;
82-
83-
// Check if this backup contains database dumps
84-
$hasDatabase = $this->backupContainsDatabase($disk, $backupFile);
76+
$tempDir = $this->extractBackup($disk, $backupFile);
77+
if (! $tempDir) {
78+
$this->error('❌ Failed to extract backup!');
8579

86-
// Extract backup ONCE jika restore database atau files
87-
if ((! $filesOnly && $hasDatabase) || ! $databaseOnly) {
88-
$tempDir = $this->extractBackup($disk, $backupFile);
89-
if (! $tempDir) {
90-
$this->error('❌ Failed to extract backup!');
91-
92-
return 1;
93-
}
80+
return 1;
9481
}
9582

96-
// Restore database first (if backup contains database and not files-only)
97-
if (! $filesOnly && $hasDatabase) {
83+
// Check database dumps
84+
$sqlFiles = File::glob($tempDir.'/db-dumps/*.sql') ?: [];
85+
$hasDatabase = ! empty($sqlFiles);
86+
87+
// Restore database
88+
if ($hasDatabase && ! $this->option('only-files')) {
9889
$this->info('🗄️ Restoring database...');
99-
if (! $this->restoreDatabase($disk, $backupFile, $tempDir)) {
100-
$success = false;
101-
}
102-
} elseif (! $filesOnly && ! $hasDatabase) {
103-
$this->info('ℹ️ No database found in backup (files-only backup)');
90+
$success = $this->restoreDatabase($tempDir) && $success;
91+
} elseif (! $hasDatabase) {
92+
$this->info('ℹ️ No database found in backup.');
93+
$success = false;
94+
} elseif ($this->option('only-files')) {
95+
$this->info('ℹ️ Skipping database restore (files-only mode).');
10496
}
10597

106-
// Restore files (if not database-only)
107-
if (! $databaseOnly && $success && $tempDir) {
108-
$this->info('📁 Restoring files...');
109-
if (! $this->restoreFiles($tempDir)) {
110-
$success = false;
111-
}
98+
// Restore files
99+
$hasOtherFolders = collect(File::directories($tempDir))
100+
->contains(fn ($dir) => basename($dir) !== 'db-dumps');
112101

113-
$this->cleanup($tempDir);
102+
if ($hasOtherFolders && ! $this->option('only-db')) {
103+
$this->info('📁 Restoring files...');
104+
$success = $this->restoreFiles($tempDir) && $success;
105+
} elseif ($this->option('only-db')) {
106+
$this->info('ℹ️ Skipping file restore (database-only mode).');
107+
} elseif (! $hasOtherFolders) {
108+
$this->info('ℹ️ No files found in backup.');
114109
}
115110

116111
if ($success) {
117112
$this->info('');
118113
$this->info('✅ Complete restore finished successfully!');
119114
$this->info('🎉 Your application is ready to use!');
120-
121-
// Suggest next steps
122115
$this->line('');
123116
$this->info('💡 Recommended next steps:');
124-
$this->line(' • Clear application cache: php artisan cache:clear');
125-
$this->line(' • Clear config cache: php artisan config:clear');
126117
$this->line(' • Check file permissions');
127118
$this->line(' • Test critical functionality');
128-
129-
return 0;
130119
} else {
131120
$this->error('❌ Restore failed!');
132-
133-
return 1;
134121
}
135122

136123
} catch (Exception $e) {
137124
$this->error('❌ Restore failed with error: '.$e->getMessage());
125+
$success = false;
126+
127+
} finally {
138128
if ($tempDir) {
139129
$this->cleanup($tempDir);
140130
}
141-
142-
return 1;
131+
$this->call('simpede:update');
132+
$this->call('maintenance', ['action' => 'stop']);
143133
}
134+
135+
return $success ? 0 : 1;
144136
}
145137

146138
private function findBackupFile($disk, $backup = null)
@@ -260,112 +252,33 @@ private function extractBackup($disk, $backupFile)
260252
}
261253
}
262254

263-
private function restoreDatabase($disk, $backupFile)
255+
private function restoreDatabase($tempDir)
264256
{
265257
try {
266-
$this->info('📥 Downloading backup file...');
267-
268-
// Download the backup file to a temporary location
269-
$tempDir = storage_path('app/temp-restore-'.time());
270-
File::makeDirectory($tempDir, 0755, true);
271-
272-
$localBackupPath = $tempDir.'/backup.zip';
273-
$this->info('⏳ Downloading from '.$disk.' disk...');
274-
275-
// Download with progress indicator
276-
$backupContent = Storage::disk($disk)->get($backupFile);
277-
if (! $backupContent) {
278-
$this->error('❌ Failed to download backup file from '.$disk.' disk');
279-
File::deleteDirectory($tempDir);
280-
281-
return false;
282-
}
283-
284-
File::put($localBackupPath, $backupContent);
285-
$this->info('✅ Backup file downloaded successfully ('.$this->formatBytes(strlen($backupContent)).')');
286-
287-
// Extract the backup
288-
$this->info('📦 Extracting backup archive...');
289-
$extractDir = $tempDir.'/extracted';
290-
File::makeDirectory($extractDir, 0755, true);
291-
292-
$zip = new ZipArchive;
293-
if ($zip->open($localBackupPath) !== true) {
294-
$this->error('❌ Failed to open backup ZIP file');
295-
File::deleteDirectory($tempDir);
296-
297-
return false;
298-
}
299-
300-
// Check if backup requires password
301-
$password = env('BACKUP_ARCHIVE_PASSWORD');
302-
if (! $password) {
303-
// Try alternative methods to get the password
304-
$password = config('backup.backup.password');
305-
}
306-
if (! $password) {
307-
// Try reading directly from .env file
308-
$envPath = base_path('.env');
309-
if (file_exists($envPath)) {
310-
$envContent = file_get_contents($envPath);
311-
if (preg_match('/BACKUP_ARCHIVE_PASSWORD=(.+)/', $envContent, $matches)) {
312-
$password = trim($matches[1]);
313-
// Remove quotes if present
314-
$password = trim($password, '"\'');
315-
}
316-
}
317-
}
318-
319-
if ($password) {
320-
$zip->setPassword($password);
321-
$this->info('🔐 Using configured backup password');
322-
} else {
323-
$this->warn('⚠️ No backup password found - trying without password');
324-
}
325-
326-
$zip->extractTo($extractDir);
327-
$zip->close();
328-
$this->info('✅ Backup extracted successfully');
329-
330258
// Find the database dump file
331-
$dbFiles = File::glob($extractDir.'/**/*.sql');
332-
if (empty($dbFiles)) {
333-
$this->error('❌ No SQL dump file found in backup');
334-
File::deleteDirectory($tempDir);
335-
336-
return false;
337-
}
338-
259+
$dbFiles = File::glob($tempDir.'/db-dumps/*.sql');
339260
$dbFile = $dbFiles[0];
340261
$this->info('🗄️ Found database dump: '.basename($dbFile));
341262

342-
// Reset database if requested
343-
if ($this->option('reset')) {
344-
$this->warn('🗑️ Dropping all existing tables...');
345-
$this->dropAllTables();
346-
}
263+
$this->warn('🗑️ Dropping all existing tables...');
264+
$this->dropAllTables();
347265

348266
// Restore the database
349267
$this->info('🚀 Restoring database from dump...');
350268
$connection = $this->option('connection') ?: config('database.default');
351269

352270
if ($this->importDatabaseDump($dbFile, $connection)) {
353271
$this->info('✅ Database restored successfully');
354-
File::deleteDirectory($tempDir);
355272

356273
return true;
357274
} else {
358275
$this->error('❌ Database restore failed');
359-
File::deleteDirectory($tempDir);
360276

361277
return false;
362278
}
363279

364280
} catch (Exception $e) {
365281
$this->error('❌ Database restore error: '.$e->getMessage());
366-
if (isset($tempDir) && File::exists($tempDir)) {
367-
File::deleteDirectory($tempDir);
368-
}
369282

370283
return false;
371284
}
@@ -569,7 +482,7 @@ private function listBackups()
569482
$this->info('📋 Available Backups');
570483
$this->line('');
571484

572-
$disks = ['local', 'google'];
485+
$disks = config('backup.backup.destination.disks');
573486
$backupName = config('backup.backup.name');
574487

575488
foreach ($disks as $disk) {
@@ -613,7 +526,7 @@ private function listBackups()
613526
}
614527

615528
$this->info('💡 To restore a specific backup:');
616-
$this->line(' php artisan backup:restore-complete --backup="filename.zip"');
529+
$this->line(' php artisan simpede:restore --backup="filename.zip"');
617530

618531
return 0;
619532
}
@@ -622,6 +535,10 @@ private function cleanup($tempDir)
622535
{
623536
if (File::exists($tempDir)) {
624537
File::deleteDirectory($tempDir);
538+
// Ensure directory is removed if still exists (sometimes File::deleteDirectory leaves empty folder)
539+
if (is_dir($tempDir)) {
540+
rmdir($tempDir);
541+
}
625542
$this->info('🧹 Cleaned up temporary files');
626543
}
627544
}
@@ -677,62 +594,6 @@ private function dropAllTables()
677594
}
678595
}
679596

680-
private function backupContainsDatabase($disk, $backupFile)
681-
{
682-
try {
683-
// Download and extract a small portion to check for database files
684-
$tempDir = storage_path('app/temp-check-'.time());
685-
File::makeDirectory($tempDir, 0755, true);
686-
687-
$localBackupPath = $tempDir.'/backup-check.zip';
688-
$backupContent = Storage::disk($disk)->get($backupFile);
689-
690-
if (! $backupContent) {
691-
File::deleteDirectory($tempDir);
692-
693-
return false;
694-
}
695-
696-
File::put($localBackupPath, $backupContent);
697-
698-
// Extract just to check contents
699-
$zip = new ZipArchive;
700-
if ($zip->open($localBackupPath) !== true) {
701-
File::deleteDirectory($tempDir);
702-
703-
return false;
704-
}
705-
706-
// Check if backup requires password
707-
$password = env('BACKUP_ARCHIVE_PASSWORD');
708-
if ($password) {
709-
$zip->setPassword($password);
710-
}
711-
712-
// Look for database files in the archive
713-
$hasDatabase = false;
714-
for ($i = 0; $i < $zip->numFiles; $i++) {
715-
$filename = $zip->getNameIndex($i);
716-
if (str_ends_with($filename, '.sql') || str_contains($filename, 'db-dumps/')) {
717-
$hasDatabase = true;
718-
break;
719-
}
720-
}
721-
722-
$zip->close();
723-
File::deleteDirectory($tempDir);
724-
725-
return $hasDatabase;
726-
727-
} catch (Exception $e) {
728-
if (isset($tempDir) && File::exists($tempDir)) {
729-
File::deleteDirectory($tempDir);
730-
}
731-
732-
return false;
733-
}
734-
}
735-
736597
private function listBackupContents($tempDir, $maxDepth = 3)
737598
{
738599
$this->listDirectoryContents($tempDir, '', $maxDepth);
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)