@@ -256,6 +256,275 @@ final class Order extends Model
256256
257257Once the trait is added, any changes to the model (create, update, delete, restore) will be automatically logged to a dedicated audit table (e.g., ` audit_orders_logs ` ).
258258
259+ ### Authenticated User Tracking
260+
261+ The audit logger automatically tracks WHO made the change and WHERE it came from:
262+
263+ ``` php
264+ // When a user makes a change via HTTP request
265+ Auth::loginUsingId(1);
266+ $order = Order::create([
267+ 'customer_id' => 123,
268+ 'total' => 99.99,
269+ 'status' => 'pending'
270+ ]);
271+
272+ // Audit log will contain:
273+ // - causer_type: "App\Models\User"
274+ // - causer_id: 1
275+ // - source: "App\Http\Controllers\OrderController@store"
276+ ```
277+
278+ ### Retrieving Audit Logs with User Information
279+
280+ You can easily retrieve audit logs with user information:
281+
282+ ``` php
283+ // Get audit logs with causer information
284+ $auditLogs = Order::find(1)->auditLogs()
285+ ->where('causer_type', 'App\Models\User')
286+ ->where('causer_id', 1)
287+ ->get();
288+
289+ // Using the EloquentAuditLog model directly
290+ use iamfarhad\LaravelAuditLog\Models\EloquentAuditLog;
291+
292+ $logs = EloquentAuditLog::forEntity(Order::class)
293+ ->forCauser('App\Models\User')
294+ ->forCauserId(1)
295+ ->get();
296+
297+ // Get logs from HTTP requests only
298+ $httpLogs = EloquentAuditLog::forEntity(Order::class)
299+ ->fromHttp()
300+ ->get();
301+
302+ // Get logs from console commands only
303+ $consoleLogs = EloquentAuditLog::forEntity(Order::class)
304+ ->fromConsole()
305+ ->get();
306+ ```
307+
308+ ### Advanced User Tracking Examples
309+
310+ #### Example 1: Track User Changes in Controller
311+
312+ ``` php
313+ <?php
314+
315+ declare(strict_types=1);
316+
317+ namespace App\Http\Controllers;
318+
319+ use App\Models\Order;
320+ use Illuminate\Http\Request;
321+
322+ final class OrderController extends Controller
323+ {
324+ public function update(Request $request, Order $order): JsonResponse
325+ {
326+ // User is already authenticated via middleware
327+ // Audit log will automatically capture:
328+ // - causer_type: "App\Models\User"
329+ // - causer_id: Auth::id()
330+ // - source: "App\Http\Controllers\OrderController@update"
331+
332+ $order->update($request->validated());
333+
334+ return response()->json(['success' => true]);
335+ }
336+ }
337+ ```
338+
339+ #### Example 2: Track System Changes in Console Commands
340+
341+ ``` php
342+ <?php
343+
344+ declare(strict_types=1);
345+
346+ namespace App\Console\Commands;
347+
348+ use App\Models\Order;
349+ use Illuminate\Console\Command;
350+
351+ final class ProcessOrdersCommand extends Command
352+ {
353+ protected $signature = 'orders:process';
354+
355+ public function handle(): void
356+ {
357+ // For console commands, causer_type and causer_id will be null
358+ // But source will be: "orders:process"
359+
360+ Order::where('status', 'pending')
361+ ->each(function ($order) {
362+ $order->update(['status' => 'processed']);
363+ });
364+ }
365+ }
366+ ```
367+
368+ #### Example 3: Custom Metadata with User Context
369+
370+ ``` php
371+ <?php
372+
373+ declare(strict_types=1);
374+
375+ namespace App\Models;
376+
377+ use Illuminate\Database\Eloquent\Model;
378+ use iamfarhad\LaravelAuditLog\Traits\Auditable;
379+
380+ final class Order extends Model
381+ {
382+ use Auditable;
383+
384+ protected $fillable = ['customer_id', 'total', 'status'];
385+
386+ /**
387+ * Add user context to audit metadata
388+ */
389+ public function getAuditMetadata(): array
390+ {
391+ return [
392+ 'ip_address' => request()->ip() ?? 'unknown',
393+ 'user_agent' => request()->userAgent() ?? 'unknown',
394+ 'user_email' => auth()->user()?->email ?? 'system',
395+ 'session_id' => session()->getId() ?? null,
396+ 'request_id' => request()->header('X-Request-Id', 'n/a'),
397+ ];
398+ }
399+ }
400+ ```
401+
402+ #### Example 4: Querying Audit Logs by User and Source
403+
404+ ``` php
405+ <?php
406+
407+ declare(strict_types=1);
408+
409+ namespace App\Services;
410+
411+ use App\Models\User;
412+ use iamfarhad\LaravelAuditLog\Models\EloquentAuditLog;
413+
414+ final class AuditReportService
415+ {
416+ public function getUserActivity(User $user, string $action = null): array
417+ {
418+ $query = EloquentAuditLog::forCauser(User::class)
419+ ->forCauserId($user->id)
420+ ->orderBy('created_at', 'desc');
421+
422+ if ($action) {
423+ $query->forAction($action);
424+ }
425+
426+ return $query->get()->map(function ($log) {
427+ return [
428+ 'entity_type' => $log->entity_type,
429+ 'entity_id' => $log->entity_id,
430+ 'action' => $log->action,
431+ 'source' => $log->source,
432+ 'created_at' => $log->created_at,
433+ 'metadata' => $log->metadata,
434+ ];
435+ })->toArray();
436+ }
437+
438+ public function getHttpRequestChanges(string $controller = null): array
439+ {
440+ $query = EloquentAuditLog::fromHttp();
441+
442+ if ($controller) {
443+ $query->fromController($controller);
444+ }
445+
446+ return $query->get()->toArray();
447+ }
448+
449+ public function getConsoleChanges(string $command = null): array
450+ {
451+ $query = EloquentAuditLog::fromConsole();
452+
453+ if ($command) {
454+ $query->fromCommand($command);
455+ }
456+
457+ return $query->get()->toArray();
458+ }
459+ }
460+ ```
461+
462+ ### Configuration for User Tracking
463+
464+ The causer (user) resolution can be configured in the ` config/audit-logger.php ` file:
465+
466+ ``` php
467+ 'causer' => [
468+ 'guard' => null, // null means use default guard, or specify 'api', 'web', etc.
469+ 'model' => null, // null means auto-detect, or specify 'App\Models\CustomUser'
470+ 'resolver' => null, // null means use default resolver, or specify custom class
471+ ],
472+ ```
473+
474+ #### Custom Causer Resolver
475+
476+ You can create a custom causer resolver for complex scenarios:
477+
478+ ``` php
479+ <?php
480+
481+ declare(strict_types=1);
482+
483+ namespace App\Services;
484+
485+ use iamfarhad\LaravelAuditLog\Contracts\CauserResolverInterface;
486+ use Illuminate\Support\Facades\Auth;
487+
488+ final class CustomCauserResolver implements CauserResolverInterface
489+ {
490+ public function resolve(): array
491+ {
492+ // Custom logic for resolving the causer
493+ if (Auth::guard('api')->check()) {
494+ $user = Auth::guard('api')->user();
495+ return [
496+ 'type' => get_class($user),
497+ 'id' => $user->id,
498+ ];
499+ }
500+
501+ if (Auth::guard('web')->check()) {
502+ $user = Auth::guard('web')->user();
503+ return [
504+ 'type' => get_class($user),
505+ 'id' => $user->id,
506+ ];
507+ }
508+
509+ // For system operations, you might want to return a system user
510+ return [
511+ 'type' => 'System',
512+ 'id' => 'system',
513+ ];
514+ }
515+ }
516+ ```
517+
518+ Register your custom resolver in a service provider:
519+
520+ ``` php
521+ // In AppServiceProvider or custom service provider
522+ $this->app->bind(
523+ \iamfarhad\LaravelAuditLog\Contracts\CauserResolverInterface::class,
524+ \App\Services\CustomCauserResolver::class
525+ );
526+ ```
527+
259528#### Excluding Fields
260529
261530To exclude specific fields from being audited, define the ` $auditExclude ` property:
0 commit comments