116 lines
4.6 KiB
PHP
116 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use Illuminate\Support\ServiceProvider;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Database\Query\Builder;
|
|
|
|
class DatabaseServiceProvider extends ServiceProvider
|
|
{
|
|
public function register()
|
|
{
|
|
//
|
|
}
|
|
|
|
public function boot()
|
|
{
|
|
DB::beforeExecuting(function ($query, $bindings) {
|
|
// Ensure query is a string before processing
|
|
if (!is_string($query)) {
|
|
return;
|
|
}
|
|
|
|
if (str_contains(strtolower($query), 'delete from')) {
|
|
try {
|
|
// Extract table name
|
|
preg_match('/delete from [`\']?(\w+)[`\']?/i', $query, $matches);
|
|
if (!isset($matches[1])) {
|
|
return;
|
|
}
|
|
|
|
$tableName = $matches[1];
|
|
|
|
// Extract WHERE clause
|
|
if (!preg_match('/where\s+(.+?)(?:order by|limit|$)/is', $query, $whereMatch)) {
|
|
Log::warning('No WHERE clause found in DELETE query', [
|
|
'table_name' => $tableName,
|
|
'query' => $query
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$whereClause = trim($whereMatch[1]);
|
|
|
|
// Count placeholders in WHERE clause
|
|
$placeholderCount = substr_count($whereClause, '?');
|
|
|
|
// Validate bindings count
|
|
if (count($bindings) < $placeholderCount) {
|
|
Log::error('Bindings count mismatch', [
|
|
'table_name' => $tableName,
|
|
'expected' => $placeholderCount,
|
|
'received' => count($bindings),
|
|
'query' => $query
|
|
]);
|
|
return;
|
|
}
|
|
|
|
// Extract only the bindings needed for WHERE clause
|
|
$whereBindings = array_slice($bindings, 0, $placeholderCount);
|
|
|
|
// Build SELECT query with proper escaping
|
|
$selectQuery = "SELECT * FROM `{$tableName}` WHERE {$whereClause}";
|
|
|
|
// Fetch records to be deleted
|
|
$recordsToDelete = DB::select($selectQuery, $whereBindings);
|
|
|
|
if (empty($recordsToDelete)) {
|
|
Log::debug('No records found to delete', [
|
|
'table_name' => $tableName,
|
|
'where_clause' => $whereClause,
|
|
'bindings' => $whereBindings
|
|
]);
|
|
return;
|
|
}
|
|
|
|
Log::debug('Preparing to log records before deletion', [
|
|
'table_name' => $tableName,
|
|
'records_count' => count($recordsToDelete)
|
|
]);
|
|
|
|
$user = Auth::user();
|
|
|
|
// Log each record before deletion
|
|
foreach ($recordsToDelete as $record) {
|
|
DB::table('deleted_records')->insert([
|
|
'table_name' => $tableName,
|
|
'record_id' => $record->id ?? null,
|
|
'deleted_data' => json_encode($record),
|
|
'deleted_by' => $user ? $user->id : null,
|
|
'deleted_by_name' => $user ? $user->name : null,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
}
|
|
|
|
Log::debug('Successfully logged records before deletion', [
|
|
'table_name' => $tableName,
|
|
'records_count' => count($recordsToDelete)
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Failed to log records before deletion', [
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString(),
|
|
'query' => $query,
|
|
'bindings' => $bindings
|
|
]);
|
|
// Don't throw exception - allow deletion to proceed
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|