whilesmart / eloquent-activities
Flexible activity tracking package for Laravel applications with actor-action-subject pattern
Package info
github.com/whilesmartphp/eloquent-activities
pkg:composer/whilesmart/eloquent-activities
Requires
- php: ^8.2
- laravel/framework: ^11.0|^12.0
Requires (Dev)
- fakerphp/faker: ^1.24
- laravel/pint: ^1.25
- orchestra/testbench: ^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
Suggests
- whilesmart/eloquent-roles: For permission-based activity management
This package is auto-updated.
Last update: 2026-03-08 19:36:52 UTC
README
Flexible activity tracking package for Laravel applications using the Actor-Action-Subject pattern.
Features
- Actor-Action-Subject Pattern: Track who did what to what
- Polymorphic Relationships: Works with any Eloquent model
- Flexible Context: Scope activities to workspaces, projects, organizations, etc.
- Multiple Sources: Track activities from manual entry, webhooks, API, system events, and integrations
- Rich Metadata: Store flexible properties and metadata with each activity
- Powerful Query Scopes: Filter activities by actor, subject, context, action, source, and date range
- Easy Integration: Simple trait to add activity tracking to any model
- Configurable: Customize routes, middleware, and features via configuration
- Laravel 11+ & 12+ Support: Compatible with modern Laravel versions
Installation
Install via Composer:
composer require whilesmart/eloquent-activities
Publish Configuration (Optional)
php artisan vendor:publish --tag=activities-config
Run Migrations
php artisan migrate
Quick Start
1. Add the Trait to Your Models
use Whilesmart\Activities\Traits\HasActivities; class Task extends Model { use HasActivities; // ... }
2. Create Activities
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(), ]);
3. Query Activities
// 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();
4. Access Model Activities
// Get all activities for a task $task->activities; // Get the latest activity timestamp $task->last_activity;
Configuration
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), ];
API Routes
If routes are enabled, the following endpoints are automatically registered:
List Activities
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 date
Create Activity
POST /api/activities
POST /api/workspaces/{workspaceId}/activities
Request Body:
{
"projectId": 1,
"startTime": "2024-01-01 10:00:00",
"summary": "Activity summary",
"description": "Activity description"
}
Activity Sources
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();
Properties and Metadata
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');
Testing
Run the test suite:
composer test
Run code style checks:
composer pint:test
Fix code style issues:
composer pint
Use Cases
- Audit Logs: Track all changes to important models
- User Activity Feeds: Show what users have been doing
- Workspace Activity: Track activities within workspace contexts
- Project Timelines: Display project-related activities
- System Events: Log important system events and actions
- Integration Tracking: Track activities from external integrations
- Time Tracking: Store time-related data in activity properties
Database Schema
The activities table includes:
- actor_type/actor_id: Who performed the activity (polymorphic)
- action: What action was performed
- subject_type/subject_id: What entity was acted upon (polymorphic, optional)
- context_type/context_id: The scope/context (workspace, project, etc., optional)
- source: Where the activity originated from
- source_id: External source identifier (optional)
- summary: Short description
- description: Detailed description
- properties: Flexible JSON data
- metadata: Additional JSON metadata
- occurred_at: When the activity occurred
- created_at/updated_at: Record timestamps
Requirements
- PHP 8.2 or higher
- Laravel 11.0 or 12.0
License
MIT License
Credits
Developed by the Whilesmart Team