Activity Model (Spatie Activity Log)
The application uses Spatie's Activity Log package (spatie/laravel-activitylog) for comprehensive activity tracking and auditing. This provides detailed logs of all changes made to models throughout the application.
Package Information
- Package:
spatie/laravel-activitylog - Model:
Spatie\Activitylog\Models\Activity - Trait:
Spatie\Activitylog\Traits\LogsActivity
Table Structure
The activity_log table contains the following columns:
id- Primary keylog_name- Name of the log (optional)description- Description of the activitysubject_type- Class name of the model being loggedsubject_id- ID of the model being loggedcauser_type- Class name of the user/model causing the activitycauser_id- ID of the user/model causing the activityproperties- JSON field containing additional dataevent- Type of event (created, updated, deleted)batch_uuid- UUID for grouping related activitiescreated_at- Timestampupdated_at- Timestamp
Configuration
The package is configured in config/activitylog.php:
php
return [
'table_name' => 'activity_log',
'database_connection' => env('DB_CONNECTION', 'mysql'),
'default_log_name' => 'default',
'subject_types' => [
'App\Models\User',
'App\Models\Product',
'App\Models\Order',
// ... other models
],
];Usage Examples
Basic Activity Logging
Models that need activity logging should include the LogsActivity trait:
php
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
class Product extends Model
{
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'price', 'is_available'])
->logOnlyDirty()
->dontSubmitEmptyLogs();
}
}Querying Activities
php
use Spatie\Activitylog\Models\Activity;
// Get all activities
$activities = Activity::all();
// Get activities for a specific model
$product = Product::find(1);
$activities = Activity::forSubject($product)->get();
// Get activities caused by a specific user
$user = User::find(1);
$activities = Activity::causedBy($user)->get();
// Get activities of a specific event type
$activities = Activity::forEvent('updated')->get();
// Get activities in a specific log
$activities = Activity::inLog('product_changes')->get();Advanced Activity Logging
php
// Log specific attributes only
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'price', 'is_available'])
->logOnlyDirty()
->dontSubmitEmptyLogs()
->logFillable();
}
// Log with custom description
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->setDescriptionForEvent(fn(string $eventName) => "This model has been {$eventName}")
->logOnlyDirty()
->dontSubmitEmptyLogs();
}
// Log with custom properties
activity()
->performedOn($product)
->causedBy($user)
->withProperties(['ip' => request()->ip()])
->log('Product viewed');Available Methods
Activity Model Methods
php
// Query scopes
Activity::forSubject($model);
Activity::causedBy($user);
Activity::forEvent('created');
Activity::inLog('log_name');
Activity::inBatch($batchUuid);
// Relationships
$activity->subject; // Get the model being logged
$activity->causer; // Get the user causing the activity
$activity->changes; // Get the changes made
$activity->properties; // Get additional propertiesLogging Helper Functions
php
// Basic logging
activity()->log('Something happened');
// Log with subject
activity()->performedOn($model)->log('Model updated');
// Log with causer
activity()->causedBy($user)->log('User action');
// Log with properties
activity()->withProperties(['key' => 'value'])->log('Action with data');
// Log with batch
activity()->useLog('batch_name')->log('Batch activity');Integration with Models
Currently, the following models use activity logging:
- User - Logs name, email, and email verification changes
- Product - Logs name, price, availability, and prescription-related fields
- Order - Logs status and amount changes
- Member - Logs member-specific changes
- Carrier - Logs carrier information changes
Activity Log Configuration Examples
User Model
php
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['name', 'email', 'email_verified_at'])
->logOnlyDirty()
->dontSubmitEmptyLogs()
->logFillable();
}Product Model
php
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly([
'name',
'price',
'is_available',
'inventory_count',
'requires_prescription',
'strength',
'dosage_form',
'active_ingredient',
'drug_class',
])
->logOnlyDirty()
->dontSubmitEmptyLogs()
->logFillable();
}Batch Operations
Activities can be grouped using batch UUIDs:
php
// Start a batch
$batchUuid = Str::uuid();
activity()
->useLog('import')
->inBatch($batchUuid)
->performedOn($product1)
->log('Product imported');
activity()
->useLog('import')
->inBatch($batchUuid)
->performedOn($product2)
->log('Product imported');
// Get all activities in a batch
$batchActivities = Activity::inBatch($batchUuid)->get();Custom Activity Descriptions
You can customize activity descriptions:
php
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->setDescriptionForEvent(fn(string $eventName) => match($eventName) {
'created' => "Product '{$this->name}' was created",
'updated' => "Product '{$this->name}' was updated",
'deleted' => "Product '{$this->name}' was deleted",
default => "Product '{$this->name}' was {$eventName}"
})
->logOnlyDirty()
->dontSubmitEmptyLogs();
}API Integration
Activity logs can be accessed through API endpoints for audit trails and reporting purposes. The logs provide a complete history of all changes made to tracked models.