where('id', $neblogisticId)->first(); if ($oldData) { $oldData = json_decode(json_encode($oldData), true); } } // Get new record if it's an insert/update if (in_array($action, ['INSERT', 'UPDATE']) && !$newData && $neblogisticId) { $newRecord = DB::table('neblogistic')->where('id', $neblogisticId)->first(); if ($newRecord) { $newData = json_decode(json_encode($newRecord), true); } } // Calculate changed fields if not provided if ($action === 'UPDATE' && !$changedFields && $oldData && $newData) { $changedFields = []; foreach ($newData as $key => $value) { $oldValue = $oldData[$key] ?? null; if ($oldValue !== $value) { $changedFields[$key] = [ 'old' => $oldValue, 'new' => $value ]; } } } // Parse browser details $browserDetails = self::parseUserAgent($requestData['user_agent'] ?? ''); $auditData = [ 'neblogistic_id' => $neblogisticId, 'action' => $action, 'old_data' => $oldData ? json_encode($oldData) : null, 'new_data' => $newData ? json_encode($newData) : null, 'changed_fields' => $changedFields ? json_encode($changedFields) : null, 'user_id' => $user ? $user->id : null, 'user_email' => $user ? ($user->email ?? null) : null, 'user_name' => $user ? ($user->name ?? null) : null, 'ip_address' => $requestData['ip'], 'user_agent' => $requestData['user_agent'], 'browser_details' => json_encode($browserDetails), 'request_url' => $requestData['url'], 'request_method' => $requestData['method'], 'created_at' => now(), ]; DB::table('neblogistic_audit_trail')->insert($auditData); return true; } catch (\Exception $e) { // Log error but don't break the main operation Log::error('Neblogistic audit trail logging failed: ' . $e->getMessage(), [ 'action' => $action, 'neblogistic_id' => $neblogisticId, 'exception' => $e ]); return false; } } /** * Get request data safely */ protected static function getRequestData($request = null) { if (!$request && request()) { $request = request(); } if (!$request) { return [ 'ip' => null, 'user_agent' => null, 'url' => null, 'method' => null, ]; } return [ 'ip' => $request->ip() ?? $request->header('X-Forwarded-For') ?? $request->server('REMOTE_ADDR') ?? 'unknown', 'user_agent' => $request->header('User-Agent'), 'url' => $request->fullUrl(), 'method' => $request->method(), ]; } /** * Parse user agent to extract browser details */ protected static function parseUserAgent($userAgent) { if (empty($userAgent)) { return [ 'browser' => 'Unknown', 'browser_version' => null, 'platform' => 'Unknown', 'device' => 'Unknown', ]; } $details = [ 'browser' => 'Unknown', 'browser_version' => null, 'platform' => 'Unknown', 'device' => 'Unknown', ]; // Detect browser if (preg_match('/MSIE|Trident/i', $userAgent)) { $details['browser'] = 'Internet Explorer'; if (preg_match('/MSIE\s([\d.]+)/', $userAgent, $matches)) { $details['browser_version'] = $matches[1]; } } elseif (preg_match('/Edge/i', $userAgent)) { $details['browser'] = 'Microsoft Edge'; if (preg_match('/Edge\/([\d.]+)/', $userAgent, $matches)) { $details['browser_version'] = $matches[1]; } } elseif (preg_match('/Chrome/i', $userAgent) && !preg_match('/Edge/i', $userAgent)) { $details['browser'] = 'Chrome'; if (preg_match('/Chrome\/([\d.]+)/', $userAgent, $matches)) { $details['browser_version'] = $matches[1]; } } elseif (preg_match('/Firefox/i', $userAgent)) { $details['browser'] = 'Firefox'; if (preg_match('/Firefox\/([\d.]+)/', $userAgent, $matches)) { $details['browser_version'] = $matches[1]; } } elseif (preg_match('/Safari/i', $userAgent) && !preg_match('/Chrome/i', $userAgent)) { $details['browser'] = 'Safari'; if (preg_match('/Version\/([\d.]+)/', $userAgent, $matches)) { $details['browser_version'] = $matches[1]; } } elseif (preg_match('/Opera|OPR/i', $userAgent)) { $details['browser'] = 'Opera'; if (preg_match('/(?:Opera|OPR)\/([\d.]+)/', $userAgent, $matches)) { $details['browser_version'] = $matches[1]; } } // Detect platform if (preg_match('/Windows/i', $userAgent)) { $details['platform'] = 'Windows'; } elseif (preg_match('/Macintosh|Mac OS X/i', $userAgent)) { $details['platform'] = 'macOS'; } elseif (preg_match('/Linux/i', $userAgent)) { $details['platform'] = 'Linux'; } elseif (preg_match('/Android/i', $userAgent)) { $details['platform'] = 'Android'; } elseif (preg_match('/iPhone|iPad|iPod/i', $userAgent)) { $details['platform'] = 'iOS'; } // Detect device if (preg_match('/Mobile|Android|iPhone|iPad/i', $userAgent)) { if (preg_match('/iPad/i', $userAgent)) { $details['device'] = 'Tablet'; } elseif (preg_match('/iPhone|iPod/i', $userAgent)) { $details['device'] = 'Mobile'; } elseif (preg_match('/Android/i', $userAgent)) { $details['device'] = preg_match('/Mobile/i', $userAgent) ? 'Mobile' : 'Tablet'; } else { $details['device'] = 'Mobile'; } } else { $details['device'] = 'Desktop'; } return $details; } /** * Clean up old audit logs (older than specified months) */ public static function cleanupOldLogs($months = 6) { try { $cutoffDate = now()->subMonths($months); $deleted = DB::table('neblogistic_audit_trail') ->where('created_at', '<', $cutoffDate) ->delete(); Log::info("Cleaned up {$deleted} old neblogistic audit trail records older than {$months} months"); return $deleted; } catch (\Exception $e) { Log::error('Failed to cleanup neblogistic audit trail logs: ' . $e->getMessage()); return 0; } } }