@@ -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 );
0 commit comments