<?php
namespace App\Http\Controllers;
use App\Models\CertificateTemplate;
use App\Models\ClassGroup;
use App\Models\ExpenseCategory;
use App\Models\Faq;
use App\Models\FeesType;
use App\Models\File as ModelsFile;
use App\Models\FormField;
use App\Models\Grade;
use App\Models\Holiday;
use App\Models\Mediums;
use App\Models\PaymentTransaction;
use App\Models\Role;
use App\Models\School;
use App\Models\SchoolSetting;
use App\Models\Section;
use App\Models\Semester;
use App\Models\SessionYear;
use App\Models\Shift;
use App\Models\Slider;
use App\Models\Staff;
use App\Models\Stream;
use App\Models\Students;
use App\Models\Subscription;
use App\Models\SystemSetting;
use App\Models\User;
use App\Repositories\DatabaseBackup\DatabaseBackupInterface;
use App\Services\BootstrapTableService;
use App\Services\ResponseService;
use App\Services\SubscriptionService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth as FacadesAuth;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Throwable;
use ZipArchive;
class DatabaseBackupController extends Controller
{
//
private DatabaseBackupInterface $databaseBackup;
private SubscriptionService $subscriptionService;
public function __construct(DatabaseBackupInterface $databaseBackup, SubscriptionService $subscriptionService)
{
$this->databaseBackup = $databaseBackup;
$this->subscriptionService = $subscriptionService;
}
public function index()
{
if ((Auth::user()->hasRole(['Super Admin', 'School Admin']) || Auth::user()->hasPermissionTo('database-backup'))) {
$schoolId = Auth::user()->hasRole('School Admin') ? Auth::user()->school_id : Auth::user()->id;
return view('database-backup.index', compact('schoolId'));
} else {
return redirect()->route('home')->with('error', "You Don't have enough permissions");
}
}
public function store()
{
ResponseService::noPermissionThenSendJson('database-backup');
if(env('DEMO_MODE') == true) {
ResponseService::errorResponse('Database backup is not allowed in demo mode');
}
$user_Id = Auth::user()->hasRole('School Admin') ? Auth::user()->school_id : Auth::user()->id;
$current_version = SystemSetting::where('name', 'system_version')->first()['data'];
if (Auth::user()->hasRole('School Admin')) {
// Database backup
$allTables = DB::select('SHOW TABLES');
$tableNames = array_map('current', $allTables);
$expectedTables = ['addons', 'attachments', 'categories', 'chats', 'failed_jobs', 'features', 'feature_sections', 'feature_section_lists', 'guidances', 'languages', 'messages', 'migrations', 'packages', 'package_features', 'password_resets', 'personal_access_tokens', 'staff_support_schools', 'system_settings', 'user_status_for_next_cycles', 'database_backups'];
$subscription = $this->subscriptionService->active_subscription(Auth::user()->school_id);
$allTables = array_diff($tableNames, $expectedTables);
$tableNames = array_values($allTables);
$staff_ids = Staff::whereHas('user', function ($q) use ($user_Id) {
$q->where('school_id', $user_Id);
})->pluck('id')->toArray();
$students = Students::where('school_id', $user_Id)->withTrashed()->get();
$student_ids = $students->pluck('user_id')->toArray();
$guardian_ids = $students->pluck('guardian_id')->toArray();
$roles_id = Role::where('school_id', Auth::user()->school_id)->pluck('id')->toArray();
$guardian_ids = array_values(array_unique($guardian_ids));
// Tables requiring additional conditions
// dd($subscription->school->admin_id);
$tablesWithAdditionalConditions = [
'users' => function ($query) use ($user_Id, $guardian_ids, $subscription) {
$query->where(function ($q) use ($user_Id, $guardian_ids) {
$q->where('school_id', $user_Id)
->orWhereIn('id', $guardian_ids);
});
// ->where(function ($q) use ($subscription) {
// $q->WhereNot('id', $subscription->school->admin_id)
// ->where('id', Auth::user()->id);
// });
},
'fees_advance' => function ($query) use ($guardian_ids) {
$query->whereIn('parent_id', $guardian_ids);
},
'staffs' => function ($query) use ($staff_ids) {
$query->whereIn('id', $staff_ids);
},
'staff_salaries' => function ($query) use ($staff_ids) {
$query->whereIn('staff_id', $staff_ids);
},
'model_has_roles' => function ($query) use ($roles_id) {
$query->whereIn('role_id', $roles_id);
},
'role_has_permissions' => function ($query) use ($roles_id) {
$query->whereIn('role_id', $roles_id);
},
'subscription_features' => function ($query) use ($subscription) {
$query->where('subscription_id', $subscription->id);
},
// Add more specific tables here
];
$backupData = '';
// dd($tableNames);
foreach ($tableNames as $table) {
// Get table creation SQL
// $createTableSQL = DB::select("SHOW CREATE TABLE `$table`");
// $backupData .= $createTableSQL[0]->{'Create Table'} . ";\n\n";
// ==========================================================
$createTableSQL = DB::select("SHOW CREATE TABLE `$table`");
$createTable = $createTableSQL[0]->{'Create Table'};
// Replace 'CREATE TABLE' with 'CREATE TABLE IF NOT EXISTS'
$createTableWithIfNotExists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $createTable);
// Add the modified SQL to the backup
$backupData .= $createTableWithIfNotExists . ";\n\n";
// ==========================================================
// Create query builder
$query = DB::table($table);
// Check if 'school_id' column exists
$hasSchoolIdColumn = Schema::hasColumn($table, 'school_id');
// Apply conditions
if ($hasSchoolIdColumn) {
if (!array_key_exists($table, $tablesWithAdditionalConditions)) {
$query->where('school_id', $user_Id);
} else {
// Apply specific conditions
$tablesWithAdditionalConditions[$table]($query);
}
} else {
// Apply specific conditions if necessary
if (array_key_exists($table, $tablesWithAdditionalConditions)) {
$tablesWithAdditionalConditions[$table]($query);
}
}
// Fetch rows and build SQL for inserts
$rows = $query->get();
foreach ($rows as $row) {
// Convert row to array
$rowArray = (array) $row;
// For class_subjects table, skip virtual_semester_id
if ($table === 'class_subjects') {
unset($rowArray['virtual_semester_id']);
}
$values = array_map(function ($value) use ($table) {
if (is_null($value)) {
return 'NULL';
}
// Special handling for settings tables that contain HTML content or email templates
if (in_array($table, ['school_settings', 'system_settings'])) {
// Check if it's an email template or contains HTML
if (
strpos($value, '<') !== false || strpos($value, '>') !== false ||
strpos($value, '{') !== false || strpos($value, '}') !== false
) {
// Properly escape HTML content and template variables
$value = str_replace('\\', '\\\\', $value); // Escape backslashes first
$value = str_replace("'", "\\'", $value); // Escape single quotes
$value = str_replace('"', '\\"', $value); // Escape double quotes
return "'" . $value . "'";
}
}
// For all other tables/content
$value = str_replace("'", "''", $value); // Escape single quotes
$value = str_replace("\\", "\\\\", $value); // Escape backslashes
return "'" . $value . "'";
}, $rowArray);
// Get column names for INSERT statement
if ($table === 'class_subjects') {
$columns = array_keys($rowArray);
$backupData .= "INSERT INTO `$table` (`" . implode('`, `', $columns) . "`) VALUES (" . implode(', ', $values) . ");\n";
} else {
$backupData .= "INSERT INTO `$table` VALUES (" . implode(', ', $values) . ");\n";
}
}
$backupData .= "\n";
}
// Define the path
$path = 'public/database-backup/schools/' . $user_Id; // Change to store in the 'sql' directory
// $path = storage_path('public/database-backup/schools/' . $user_Id);
$timestamp = Carbon::now()->format('Y-m-d');
$file_name = "database_backup_{$user_Id}_{$timestamp}";
$filePath = $path . "/database_backup_{$user_Id}_{$timestamp}.sql";
// check storage public in id folder exist
if (!Storage::exists('public/' . $user_Id)) {
Storage::makeDirectory('public/' . $user_Id);
}
// Create the directory if it doesn't exist
if (!Storage::exists($path)) {
Storage::makeDirectory($path);
}
// Save the backup to the file
Storage::put($filePath, $backupData);
// End database backup
// ==========================================================
$zip = new ZipArchive;
$backup_type = 'schools';
$public_folder_path = storage_path('app/public/' . $user_Id);
$backup_folder_path = storage_path('app/public/database-backup/' . $backup_type . '/' . $user_Id);
$zip_file_path = $backup_folder_path . '/' . $file_name . '-(V-' . $current_version . ').zip';
// dd(File::isDirectory($backup_folder_path));
// $mainFolder = Auth::user()->id; // Main folder name
// $mainFolderPath = storage_path('app/public/database-backup/super-admin/' . $mainFolder); // Path to the main folder
if ($zip->open($zip_file_path, ZipArchive::CREATE) === TRUE) {
if (File::isDirectory($backup_folder_path)) {
// Add main folder to the zip
$zip_media_folder = 'media';
// create folder for media files
$zip->addEmptyDir($zip_media_folder);
// create database-backup folder and add .sql file
$relativeSqlFile = 'database-backup/database_backup_' . $user_Id . '_' . $timestamp . '.sql';
$zip->addFile(storage_path('app/' . $filePath), $relativeSqlFile);
// dd($relativeSqlFile);
// // Get all subdirectories inside the main folder
$subfolders = File::directories($public_folder_path);
foreach ($subfolders as $subfolderPath) {
// Get the relative path of the subfolder
$relativeSubfolder = $zip_media_folder . '/' . str_replace(storage_path('app/public/'), '', $subfolderPath);
// Add the subfolder to the zip
$zip->addEmptyDir($relativeSubfolder);
// Get all files inside the current subfolder
$files = File::files($subfolderPath);
foreach ($files as $file) {
// Get the relative path of the file
$relativeFile = $zip_media_folder . '/' . str_replace(storage_path('app/public/'), '', $file);
// Add the file to the zip with its relative path
$zip->addFile($file, $relativeFile);
}
}
// // Add files in the main folder
// $mainFolderFiles = File::files($mainFolderPath);
// foreach ($mainFolderFiles as $file) {
// // Get the relative path of the file
// $relativeFile = str_replace(storage_path('app/public/'), '', $file);
// // Add the file to the zip
// $zip->addFile($file, $relativeFile);
// }
// Close the archive
$zip->close();
// Create the directory if it doesn't exist
if (!Storage::exists($path)) {
Storage::makeDirectory($path);
}
}
// Delete the .sql file after zipping
Storage::delete($filePath);
$data = [
'name' => $file_name
];
// $this->databaseBackup->create($data);
$file_name = "database_backup_{$user_Id}_" . Carbon::now()->format('Y-m-d') . '-(V-' . $current_version . ').zip';
// dd($file_name);
$zipFileDownload = 'database-backup/schools/' . $user_Id . '/' . $file_name;
$download_url = url(Storage::url($zipFileDownload));
ResponseService::successResponse('Backup completed successfully', $download_url);
} else {
ResponseService::logErrorResponse("DatabaseBackup Controller -> Store Method");
ResponseService::errorResponse();
}
} else if (Auth::user()->hasRole('Super Admin')) {
// Set default connection for Super Admin
DB::setDefaultConnection('mysql');
// Get all tables
$allTables = DB::select('SHOW TABLES');
$tableNames = array_map('current', $allTables);
$backupData = '';
$expectedTables = ['addons', 'failed_jobs', 'features', 'feature_sections', 'feature_section_lists', 'guidances', 'languages', 'migrations', 'packages', 'package_features', 'password_resets', 'personal_access_tokens', 'staff_support_schools', 'system_settings'];
$allTables = array_diff($tableNames, $expectedTables);
$tableNames = array_values($allTables);
// Loop through each table and generate backup data
foreach ($tableNames as $table) {
$createTableSQL = DB::select("SHOW CREATE TABLE `$table`");
$createTable = $createTableSQL[0]->{'Create Table'};
$createTableWithIfNotExists = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $createTable);
$backupData .= $createTableWithIfNotExists . ";\n\n";
$query = DB::table($table);
$rows = $query->get();
foreach ($rows as $row) {
$values = array_map(function ($value) {
return is_null($value) ? 'NULL' : "'" . addslashes($value) . "'";
}, (array) $row);
$backupData .= "INSERT INTO `$table` VALUES (" . implode(', ', $values) . ");\n";
}
$backupData .= "\n";
}
// Define the path
$path = 'public/database-backup/super-admin/' . $user_Id; // Change to store in the 'sql' directory
$timestamp = Carbon::now()->format('Y-m-d');
$file_name = "database_backup_{$user_Id}_{$timestamp}";
$filePath = $path . "/database_backup_{$user_Id}_{$timestamp}.sql";
// check storage public in id folder exist
if (!Storage::exists('public/' . $user_Id)) {
Storage::makeDirectory('public/' . $user_Id);
}
// Create the directory if it doesn't exist
if (!Storage::exists($path)) {
Storage::makeDirectory($path);
}
// Save the backup to the file
Storage::put($filePath, $backupData);
// End database backup
// ==========================================================
$zip = new ZipArchive;
$backup_type = 'super-admin';
$public_folder_path = storage_path('app/public/' . $user_Id);
$backup_folder_path = storage_path('app/public/database-backup/' . $backup_type . '/' . $user_Id);
$zip_file_path = $backup_folder_path . '/' . $file_name . '-(V-' . $current_version . ').zip';
// dd(File::isDirectory($backup_folder_path));
// $mainFolder = Auth::user()->id; // Main folder name
// $mainFolderPath = storage_path('app/public/database-backup/super-admin/' . $mainFolder); // Path to the main folder
if ($zip->open($zip_file_path, ZipArchive::CREATE) === TRUE) {
if (File::isDirectory($backup_folder_path)) {
// Add main folder to the zip
$zip_media_folder = 'media';
// create folder for media files
$zip->addEmptyDir($zip_media_folder);
// create database-backup folder and add .sql file
$relativeSqlFile = 'database-backup/database_backup_' . $user_Id . '_' . $timestamp . '.sql';
$zip->addFile(storage_path('app/' . $filePath), $relativeSqlFile);
// dd($relativeSqlFile);
// // Get all subdirectories inside the main folder
$subfolders = File::directories($public_folder_path);
foreach ($subfolders as $subfolderPath) {
// Get the relative path of the subfolder
$relativeSubfolder = $zip_media_folder . '/' . str_replace(storage_path('app/public/'), '', $subfolderPath);
// Add the subfolder to the zip
$zip->addEmptyDir($relativeSubfolder);
// Get all files inside the current subfolder
$files = File::files($subfolderPath);
foreach ($files as $file) {
// Get the relative path of the file
$relativeFile = $zip_media_folder . '/' . str_replace(storage_path('app/public/'), '', $file);
// Add the file to the zip with its relative path
$zip->addFile($file, $relativeFile);
}
}
// // Add files in the main folder
// $mainFolderFiles = File::files($mainFolderPath);
// foreach ($mainFolderFiles as $file) {
// // Get the relative path of the file
// $relativeFile = str_replace(storage_path('app/public/'), '', $file);
// // Add the file to the zip
// $zip->addFile($file, $relativeFile);
// }
// Close the archive
$zip->close();
// Create the directory if it doesn't exist
if (!Storage::exists($path)) {
Storage::makeDirectory($path);
}
}
// Delete the .sql file after zipping
Storage::delete($filePath);
$data = [
'name' => $file_name
];
// $this->databaseBackup->create($data);
$file_name = "database_backup_{$user_Id}_" . Carbon::now()->format('Y-m-d') . '-(V-' . $current_version . ').zip';
$zipFileDownload = 'database-backup/super-admin/' . $user_Id . '/' . $file_name;
$download_url = url(Storage::url($zipFileDownload));
ResponseService::successResponse('Backup completed successfully', $download_url);
} else {
ResponseService::logErrorResponse("DatabaseBackup Controller -> Store Method");
ResponseService::errorResponse();
}
}
}
public function show()
{
ResponseService::noPermissionThenRedirect('database-backup');
if(env('DEMO_MODE') == true) {
ResponseService::errorResponse('Database backup is not allowed in demo mode');
}
$offset = request('offset', 0);
$limit = request('limit', 10);
$sort = request('sort', 'id');
$order = request('order', 'DESC');
$search = request('search');
$sql = $this->databaseBackup->builder()
->where(function ($query) use ($search) {
$query->when($search, function ($query) use ($search) {
$query->where(function ($query) use ($search) {
$query->where('id', 'LIKE', "%$search%")->orwhere('title', 'LIKE', "%$search%")->orwhere('description', 'LIKE', "%$search%")->orwhere('date', 'LIKE', "%$search%");
});
});
});
$total = $sql->count();
if ($offset >= $total && $total > 0) {
$lastPage = floor(($total - 1) / $limit) * $limit; // calculate last page offset
$offset = $lastPage;
}
$sql->orderBy($sort, $order)->skip($offset)->take($limit);
$res = $sql->get();
$bulkData = array();
$bulkData['total'] = $total;
$rows = array();
$no = 1;
foreach ($res as $row) {
$operate = BootstrapTableService::button('fa fa-refresh', '#', ['restore-database', 'btn-gradient-info'], ['title' => trans("restore"), 'data-id' => $row->id]);
$operate .= BootstrapTableService::deleteButton(url('database-backup', $row->id));
$tempRow = $row->toArray();
$tempRow['no'] = $no++;
$tempRow['operate'] = $operate;
$rows[] = $tempRow;
}
$bulkData['rows'] = $rows;
return response()->json($bulkData);
}
public function destroy($id)
{
ResponseService::noPermissionThenSendJson('database-backup');
if(env('DEMO_MODE') == true) {
ResponseService::errorResponse('Database backup is not allowed in demo mode');
}
try {
$databaseBackup = $this->databaseBackup->findById($id);
$sql_file = 'database-backup/' . Auth::user()->school_id . '/' . $databaseBackup->name . '.sql';
$zip_file = 'database-backup/' . Auth::user()->school_id . '/' . $databaseBackup->name . '.zip';
if (Storage::disk('public')->exists($sql_file)) {
Storage::disk('public')->delete($sql_file);
}
if (Storage::disk('public')->exists($zip_file)) {
Storage::disk('public')->delete($zip_file);
}
$this->databaseBackup->deleteById($id);
ResponseService::successResponse('Data Deleted Successfully');
} catch (Throwable $e) {
ResponseService::logErrorResponse($e, "DatabaseBackup Controller -> Destroy Method");
ResponseService::errorResponse();
}
}
public function restore(Request $request)
{
if(env('DEMO_MODE') == true) {
ResponseService::errorResponse('Database backup is not allowed in demo mode');
}
$validator = Validator::make($request->all(), [
'zip_file' => 'required|mimes:zip',
]);
if ($validator->fails()) {
ResponseService::errorResponse($validator->errors()->first());
}
try {
$authId = Auth::user()->hasRole('School Admin') ? Auth::user()->school_id : Auth::user()->id;
if (Auth::user()->hasRole('School Admin')) {
// File UnZip
$zip = new ZipArchive;
$backup_type = 'schools';
$public_folder_path = storage_path('app/public/' . $authId);
$backup_folder_path = storage_path('app/public/database-backup/' . $backup_type . '/' . $authId);
// Ensure the school ID folder exists
if (!file_exists($public_folder_path)) {
File::makeDirectory($public_folder_path, 0755, true);
}
// Old Data Delete from public folder
$mainOldfolders = File::directories($public_folder_path);
// dd("School Admin",$mainOldfolders);
foreach ($mainOldfolders as $subfolder) {
foreach (File::files($subfolder) as $file) {
File::delete($file);
}
}
// Un-Zip and move data
if ($zip->open($request->zip_file) === TRUE) {
$zip->extractTo($backup_folder_path);
$mainfolders = File::directories($backup_folder_path);
foreach ($mainfolders as $subfolder) {
// Check if the folder doesn't contain the specific 'database-backup' path
if (!Str::contains($subfolder, $authId . "/database-backup")) {
if (File::isDirectory($subfolder . '/' . $authId)) {
// Get the list of subfolders
$mainSubfolders = File::directories($subfolder . '/' . $authId);
// Iterate through each subfolder
foreach ($mainSubfolders as $folder) {
$folderName = basename($folder);
// Build the destination path for the folder
$destinationPath = $public_folder_path . "/" . $folderName;
File::move($folder, $destinationPath);
}
}
}
}
$zip->close();
}
// Read Backup .sql File
$sql_file_path = "";
foreach (File::directories($backup_folder_path) as $subfolders) {
foreach (File::files($subfolders) as $subfolders) {
$sql_file_path = pathinfo($subfolders)['dirname'] . "/" . pathinfo($subfolders)['basename'];
}
}
try {
DB::beginTransaction();
DB::statement("SET FOREIGN_KEY_CHECKS = 0");
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
$expectedTables = ['addons', 'attachments', 'categories', 'chats', 'failed_jobs', 'features', 'feature_sections', 'feature_section_lists', 'guidances', 'languages', 'messages', 'migrations', 'packages', 'package_features', 'password_resets', 'personal_access_tokens', 'staff_support_schools', 'system_settings', 'user_status_for_next_cycles', 'database_backups'];
$allTables = array_diff($tables, $expectedTables);
$tableNames = array_values($allTables);
// dd($tableNames);
foreach ($tableNames as $table) {
DB::table($table)->truncate();
\Log::info("Table {$table} truncated.");
}
DB::statement("SET FOREIGN_KEY_CHECKS = 1");
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
\Log::error('Truncation error: ' . $e->getMessage());
}
// Check if the SQL file exists and proceed with execution
if (File::exists($sql_file_path)) {
// Read the contents of the SQL file
$sql = File::get($sql_file_path);
$queries = array_filter(
explode(";\n", $sql),
function ($query) {
return !empty(trim($query));
}
);
try {
// Begin transaction
DB::beginTransaction();
DB::statement("SET FOREIGN_KEY_CHECKS = 0");
foreach ($queries as $query) {
if (!empty(trim($query))) {
DB::unprepared(trim($query));
\Log::info("Executed query: {$query}");
}
}
DB::statement("SET FOREIGN_KEY_CHECKS = 1");
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
\Log::error("Transaction failed: " . $e->getMessage());
}
} else {
\Log::warning('SQL file not found: ' . $sql_file_path);
}
// Delete backup folders and .sql files after backup
$deleteBackupFolders = File::directories($backup_folder_path);
foreach ($deleteBackupFolders as $subfolder) {
if (Str::contains($subfolder, $authId . "/database-backup")) {
// Delete all .sql files in the subfolder
foreach (File::files($subfolder) as $subpath) {
if (pathinfo($subpath)['extension'] === 'sql') {
File::delete($subpath);
}
}
// Delete the subfolder after its contents have been deleted
File::deleteDirectory($subfolder);
}
}
// add school current version migration
$schools = School::withTrashed()->where('id', Auth::user()->school_id)->get();
foreach ($schools as $key => $school) {
Config::set('database.connections.school.database', $school->database_name);
DB::purge('school');
DB::connection('school')->reconnect();
DB::setDefaultConnection('school');
Artisan::call('migrate', [
'--database' => 'school',
'--path' => 'database/migrations/schools',
'--force' => true,
]);
}
} else if (Auth::user()->hasRole('Super Admin')) {
// File UnZip
$zip = new ZipArchive;
$backup_type = 'super-admin';
$public_folder_path = storage_path('app/public/' . $authId);
$backup_folder_path = storage_path('app/public/database-backup/' . $backup_type . '/' . $authId);
// Ensure the school ID folder exists
if (!file_exists($public_folder_path)) {
File::makeDirectory($public_folder_path, 0755, true);
}
// Old Data Delete from public folder
$mainOldfolders = File::directories($public_folder_path);
// dd("School Admin",$mainOldfolders);
foreach ($mainOldfolders as $subfolder) {
foreach (File::files($subfolder) as $file) {
File::delete($file);
}
}
// Un-Zip and move data
if ($zip->open($request->zip_file) === TRUE) {
$zip->extractTo($backup_folder_path);
$mainfolders = File::directories($backup_folder_path);
foreach ($mainfolders as $subfolder) {
// Check if the folder doesn't contain the specific 'database-backup' path
if (!Str::contains($subfolder, $authId . "/database-backup")) {
if (File::isDirectory($subfolder . '/' . $authId)) {
// Get the list of subfolders
$mainSubfolders = File::directories($subfolder . '/' . $authId);
// Iterate through each subfolder
foreach ($mainSubfolders as $folder) {
$folderName = basename($folder);
// Build the destination path for the folder
$destinationPath = $public_folder_path . "/" . $folderName;
File::move($folder, $destinationPath);
}
}
}
}
$zip->close();
}
// Read Backup .sql File
$sql_file_path = "";
foreach (File::directories($backup_folder_path) as $subfolders) {
foreach (File::files($subfolders) as $subfolders) {
$sql_file_path = pathinfo($subfolders)['dirname'] . "/" . pathinfo($subfolders)['basename'];
}
}
try {
// Start the transaction
DB::beginTransaction();
// Disable foreign key checks
DB::statement("SET FOREIGN_KEY_CHECKS = 0");
// Get all table names
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
$expectedTables = ['addons', 'attachments', 'categories', 'chats', 'failed_jobs', 'features', 'feature_sections', 'feature_section_lists', 'guidances', 'languages', 'messages', 'migrations', 'packages', 'package_features', 'password_resets', 'personal_access_tokens', 'staff_support_schools', 'system_settings', 'user_status_for_next_cycles', 'database_backups'];
$allTables = array_diff($tables, $expectedTables);
$tableNames = array_values($allTables);
// Loop through each table and truncate
foreach ($tableNames as $table) {
// You can use `DB::table($table)->truncate()` or use raw SQL for truncation
DB::table($table)->truncate();
\Log::info("Table {$table} truncated.");
}
// Re-enable foreign key checks
DB::statement("SET FOREIGN_KEY_CHECKS = 1");
// Commit the transaction
DB::commit();
} catch (\Exception $e) {
// Rollback the transaction if an error occurs
DB::rollBack();
\Log::error('Truncation error: ' . $e->getMessage());
}
// Check if the SQL file exists and proceed with execution
if (File::exists($sql_file_path)) {
// Read the contents of the SQL file
$sql = File::get($sql_file_path);
$queries = array_filter(
explode(";\n", $sql),
function ($query) {
return !empty(trim($query));
}
);
try {
// Begin transaction
DB::beginTransaction();
DB::statement("SET FOREIGN_KEY_CHECKS = 0");
foreach ($queries as $query) {
if (!empty(trim($query))) {
DB::unprepared(trim($query));
\Log::info("Executed query: {$query}");
}
}
DB::statement("SET FOREIGN_KEY_CHECKS = 1");
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
\Log::error("Transaction failed: " . $e->getMessage());
}
} else {
\Log::warning('SQL file not found: ' . $sql_file_path);
}
// Delete backup folders and .sql files after backup
$deleteBackupFolders = File::directories($backup_folder_path);
foreach ($deleteBackupFolders as $subfolder) {
if (Str::contains($subfolder, $authId . "/database-backup")) {
// Delete all .sql files in the subfolder
foreach (File::files($subfolder) as $subpath) {
if (pathinfo($subpath)['extension'] === 'sql') {
File::delete($subpath);
}
}
// Delete the subfolder after its contents have been deleted
File::deleteDirectory($subfolder);
}
}
}
ResponseService::successResponse('Data Restore Successfully');
} catch (\Throwable $th) {
DB::rollBack();
ResponseService::logErrorResponse($th, "DatabaseBackup Controller -> Restore Method");
ResponseService::errorResponse();
}
}
public function getTableNameFromQuery($query)
{
if (preg_match('/CREATE TABLE `?(\w+)`?/', $query, $matches)) {
return $matches[1];
}
return null;
}
public function deleteOldRecords($subscription)
{
$schoolId = $subscription->school_id;
if ($subscription) {
$guardian_ids = Students::where('school_id', $schoolId)->pluck('guardian_id')->toArray();
Mediums::where('school_id', $schoolId)->delete();
User::where('school_id', $schoolId)->whereNot('id', Auth::user()->id)->whereNot('id', $subscription->school->admin_id)->delete();
User::whereIn('id', $guardian_ids)->delete();
CertificateTemplate::where('school_id', $schoolId)->delete();
ClassGroup::where('school_id', $schoolId)->delete();
ExpenseCategory::where('school_id', $schoolId)->delete();
Faq::where('school_id', $schoolId)->delete();
FeesType::where('school_id', $schoolId)->delete();
ModelsFile::where('school_id', $schoolId)->delete();
FormField::where('school_id', $schoolId)->delete();
SessionYear::where('school_id', $schoolId)->delete();
Grade::where('school_id', $schoolId)->delete();
Holiday::where('school_id', $schoolId)->delete();
SchoolSetting::where('school_id', $schoolId)->delete();
Section::where('school_id', $schoolId)->delete();
Semester::where('school_id', $schoolId)->delete();
Shift::where('school_id', $schoolId)->delete();
Slider::where('school_id', $schoolId)->delete();
Stream::where('school_id', $schoolId)->delete();
Subscription::where('school_id', $schoolId)->delete();
PaymentTransaction::where('school_id', $schoolId)->delete();
}
}
}