// app/Http/Controllers/DatabaseRestoreController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Log; use Symfony\Component\Process\Process; use Symfony\Component\Process\Exception\ProcessFailedException; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; class DatabaseRestoreController extends Controller { public function restoreApi(Request $request) { $validator = Validator::make($request->all(), [ 'database_dump' => 'required|mimes:gz,tar,tgz|max:500000', ]); if ($validator->fails()) { return response()->json(['error' => $validator->errors()], 422); } $file = $request->file('database_dump'); $fileName = time() . '.' . $file->getClientOriginalExtension(); $filePath = $file->storeAs('db-backups', $fileName); $storagePath = Storage::path($filePath); $tempDir = storage_path('app/temp_restore'); // Ensure temp directory exists if (!is_dir($tempDir)) { mkdir($tempDir, 0755, true); } try { // 1. Extract the .tar.gz file $extractProcess = new Process(['tar', '-xzf', $storagePath, '-C', $tempDir]); $extractProcess->run(); if (!$extractProcess->isSuccessful()) { throw new ProcessFailedException($extractProcess); } $sqlFiles = glob($tempDir . '/*.sql'); if (empty($sqlFiles)) { return response()->json(['error' => 'SQL file not found in the archive.'], 422); } $sqlFile = $sqlFiles; // 2. Restore the .sql file using mysql command $dbConfig = config('database.connections.mysql'); $dbName = $dbConfig['database']; $dbUser = $dbConfig['username']; $dbPass = $dbConfig['password']; $dbHost = $dbConfig['host']; $command = sprintf( 'mysql -h%s -u%s -p%s %s < %s', escapeshellarg($dbHost), escapeshellarg($dbUser), escapeshellarg($dbName), escapeshellarg($sqlFile) ); exec($command, $output, $returnCode); if ($returnCode !== 0) { Log::error('Database restore command failed: ' . implode("\n", $output)); return response()->json(['error' => 'Database restoration failed. Check application logs for details.'], 500); } Log::info("Database restored successfully from API endpoint."); // --- Updated Success Response --- return response()->json(['message' => 'restore successful'], 200); // -------------------------------- } catch (ProcessFailedException $exception) { Log::error('Extraction process failed: ' . $exception->getMessage()); return response()->json(['error' => 'File extraction or restoration failed.'], 500); } finally { // Clean up temporary files (helper method deleteDir must be included from previous response) if (file_exists($storagePath)) { Storage::delete($filePath); } if (is_dir($tempDir)) { $this->deleteDir($tempDir); } } } // Helper function to delete directory recursively (include this in your class) private function deleteDir($dirPath) { if (! is_dir($dirPath)) { return; } $files = glob($dirPath . '/*'); foreach ($files as $file) { if (is_file($file)) { unlink($file); } elseif (is_dir($file)) { $this->deleteDir($file); } } rmdir($dirPath); } }