| Install | |
|---|---|
composer require whilesmart/eloquent-activities |
|
| PHP: | ^8.2 |
Flexible activity tracking package for Laravel applications using the Actor-Action-Subject pattern.
Install via Composer:
composer require whilesmart/eloquent-activities
php artisan vendor:publish --tag=activities-config
php artisan migrate
use Whilesmart\Activities\Traits\HasActivities;
class Task extends Model
{
use HasActivities;
// ...
}
use Whilesmart\Activities\Models\Activity;
// Simple activity
Activity::create([
'actor_type' => User::class,
'actor_id' => $user->id,
'action' => 'created',
'subject_type' => Task::class,
'subject_id' => $task->id,
'source' => Activity::SOURCE_MANUAL,
'summary' => 'Task created',
'description' => 'User created a new task',
'occurred_at' => now(),
]);
// Activity with context (workspace-scoped)
Activity::create([
'actor_type' => User::class,
'actor_id' => $user->id,
'action' => 'updated',
'subject_type' => Task::class,
'subject_id' => $task->id,
'context_type' => Workspace::class,
'context_id' => $workspace->id,
'source' => Activity::SOURCE_SYSTEM,
'summary' => 'Task updated',
'occurred_at' => now(),
]);
// Activity with properties and metadata
Activity::create([
'action' => 'login',
'actor_type' => User::class,
'actor_id' => $user->id,
'source' => Activity::SOURCE_SYSTEM,
'properties' => [
'ip_address' => request()->ip(),
'duration' => 3600,
],
'metadata' => [
'browser' => 'Chrome',
'version' => '120.0',
],
'occurred_at' => now(),
]);
// Get activities for a specific user
$activities = Activity::forActor(User::class, $user->id)->get();
// Get activities for a specific task
$activities = Activity::forSubject(Task::class, $task->id)->get();
// Get activities within a workspace context
$activities = Activity::inContext(Workspace::class, $workspace->id)->get();
// Filter by action
$activities = Activity::byAction('created')->get();
// Filter by source
$activities = Activity::bySource(Activity::SOURCE_WEBHOOK)->get();
// Filter by date range
$activities = Activity::inDateRange('2024-01-01', '2024-01-31')->get();
// Chain scopes for complex queries
$activities = Activity::forActor(User::class, $user->id)
->forSubject(Task::class, $task->id)
->inContext(Workspace::class, $workspace->id)
->byAction('created')
->latest('occurred_at')
->get();
// Get all activities for a task
$task->activities;
// Get the latest activity timestamp
$task->last_activity;
The package provides several configuration options in config/activities.php:
return [
// Model Configuration
'user_model' => env('ACTIVITIES_USER_MODEL', 'App\\Models\\User'),
'workspace_model' => env('ACTIVITIES_WORKSPACE_MODEL', 'App\\Models\\Workspace'),
'project_model' => env('ACTIVITIES_PROJECT_MODEL', 'App\\Models\\Project'),
// Route Configuration
'register_routes' => env('ACTIVITIES_REGISTER_ROUTES', true),
'route_prefix' => env('ACTIVITIES_ROUTE_PREFIX', ''),
'route_middleware' => ['auth:sanctum'],
// Feature Flags
'workspace_scoped' => env('ACTIVITIES_WORKSPACE_SCOPED', true),
'project_scoped' => env('ACTIVITIES_PROJECT_SCOPED', true),
'allow_manual_creation' => env('ACTIVITIES_ALLOW_MANUAL', true),
'allow_webhook_creation' => env('ACTIVITIES_ALLOW_WEBHOOK', true),
];
If routes are enabled, the following endpoints are automatically registered:
GET /api/activities
GET /api/workspaces/{workspaceId}/activities
Query Parameters:
projectId - Filter by projectmemberId - Filter by user/memberfrom - Filter by start dateto - Filter by end datePOST /api/activities
POST /api/workspaces/{workspaceId}/activities
Request Body:
{
"projectId": 1,
"startTime": "2024-01-01 10:00:00",
"summary": "Activity summary",
"description": "Activity description"
}
The package supports multiple activity sources:
Activity::SOURCE_MANUAL // User-created activities
Activity::SOURCE_WEBHOOK // Activities from webhooks
Activity::SOURCE_API // Activities from API calls
Activity::SOURCE_SYSTEM // System-generated activities
Activity::SOURCE_INTEGRATION // Activities from integrations
Check activity source:
$activity->isManual();
$activity->isFromWebhook();
$activity->isSystem();
Store flexible data with activities:
// Set properties
$activity->setProperty('duration', 3600);
$activity->setProperty('priority', 'high');
$activity->save();
// Get properties
$activity->getProperty('duration');
$activity->getProperty('priority', 'default_value');
// Set metadata
$activity->setMetadata(['browser' => 'Chrome', 'version' => '120.0']);
$activity->setMetadata('browser', 'Chrome');
$activity->save();
// Get metadata
$activity->getMetadata();
$activity->getMetadata('browser');
Run the test suite:
composer test
Run code style checks:
composer pint:test
Fix code style issues:
composer pint
The activities table includes:
MIT License
Developed by the Whilesmart Team