Spatie Laravel Activity Log

1.7k Views Asked by At

Is there a way to include customization of ActivityLog

I'm looking for a way to included the events and properties affected in the description such that it shows specifics. For example User A updated their email address to [email protected]. Considering that properties keeps track of the changes.

Also, is there a way to isolate the events fired? Like say, if a user creates and account.

I currently have the below code in my user model but i want for more customization

<?php

namespace App\Models;

use App\Notifications\MyWelcomeNotification;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\CausesActivity;
use Spatie\Permission\Traits\HasRoles;
use Spatie\WelcomeNotification\ReceivesWelcomeNotification;

class User extends Authenticatable
{
    use HasApiTokens;
    use HasFactory;
    use HasProfilePhoto;
    use Notifiable;
    use TwoFactorAuthenticatable;
    use HasRoles;
    use ReceivesWelcomeNotification;
    use LogsActivity;
    use CausesActivity;
    

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'age',
        'gender',
        'fitness_level',
        'fitness_location',
        'fitness_goal',
        'height',
        'weight',
        'fitness_frequency',
        'email',
        'email_verified_at',
        'phone',
        'phone_verified_at',
        'password',
        'firebase_uid',
        'api_key',
        'device_token',
        'status',
        'subscription',
        'profile_photo_path',
        'referal_code',
    ];


    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_recovery_codes',
        'two_factor_secret',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [
        'profile_photo_url',
    ];

    public function sendWelcomeNotification(Carbon $validUntil)
    {
        $this->notify(new MyWelcomeNotification($validUntil));
    }

    public function getActivitylogOptions(): LogOptions { 
        return LogOptions::defaults()
                        ->logOnly([ 'name', 'age', 'fitness_level', 'fitness_location', 'fitness_goal', 'height', 'weight', 'fitness_frequency', 'email', 'phone', 'status', 'subscription'])
                        ->logOnlyDirty()
                        ->dontSubmitEmptyLogs()
                        ->setDescriptionForEvent(fn(string $eventName) => auth()->user()->name." {$eventName} ".$this->getDirty()); 
    }


    public function enrolInWorkout() {
        return $this->belongsToMany(Workout::class, 'user_workout', 'user_id', 'workout_id')->withTimestamps();
    }
}

I also know to use the below but it requires me to programmatically write the logs. I was looking for something more dynamic.

activity()
   ->performedOn($anEloquentModel)
   ->causedBy($user)
   ->withProperties(['customProperty' => 'customValue'])
   ->log('Look, I logged something');
1

There are 1 best solutions below

0
On

TO isolate the type of events like created, updated, and deleted you can add this in your model class

protected static $logAttributes = ["*"];

OR

protected static $logAttributes = ["Created", "Updated", "Deleted"];

Also, you can customize the name of the log specifically like

protected static $logName = 'User log';

To save only changed values in The properties column like if only email is changed you have to add this in the model class to save only updated column data

  protected static $logOnlyDirty = true;