Files
citrus-cms/app/Providers/DatabaseServiceProvider.php
2026-04-28 21:14:25 +03:00

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
}
}
});
}
}