ActivityLogger
AppServicesActivityLogger — static utility class. Writes audit records to the activity_logs table. Never throws exceptions; errors are silently swallowed so a logging failure never interrupts the request.
Usage
use AppServicesActivityLogger;
ActivityLogger::log('post.created', 'post', $post->id, 'New post created: ' . $post->title);
Method Signature
public static function log(
string $action,
string $subjectType,
int $subjectId,
string $description = ''
): void
| Parameter | Description |
|---|---|
$action | Dot-notation action string (e.g. post.created, theme.activated) |
$subjectType | The type of entity acted on (e.g. post, theme, plugin, user) |
$subjectId | Primary key of the entity |
$description | Human-readable description for the admin activity feed |
What Is Recorded
Each call inserts one row into activity_logs:
| Column | Value |
|---|---|
user_id | Current authenticated user ID (or 0 for CLI/system) |
username | Current authenticated username (or 'system') |
action | The $action string |
subject_type | The $subjectType string |
subject_id | The $subjectId integer |
description | The $description string |
ip_address | $_SERVER['REMOTE_ADDR'] (or CLI marker) |
created_at | NOW() |
Common Action Strings
Pubvana core uses these action strings consistently. Extension code should follow the same convention:
| Action | Triggered by |
|---|---|
post.created | New post saved |
post.updated | Post edited |
post.deleted | Post trashed |
post.published | Post status changed to published |
page.created / page.updated | Page CRUD |
theme.activated | Theme switched |
theme.deactivated | Theme disabled |
plugin.activated | Plugin activated |
plugin.deactivated | Plugin deactivated |
widget.placed | Widget instance added to area |
settings.updated | Admin settings saved |
media.uploaded | File uploaded |
user.created / user.updated | User management |
marketplace.installed | Extension installed from marketplace |
Usage Patterns
After creating a resource
$id = model('ItemModel')->insert($data);
ActivityLogger::log('item.created', 'item', $id, 'Item created: ' . $data['title']);
After bulk operations
foreach ($posts as $post) {
$postModel->update($post->id, ['status' => 'published']);
}
ActivityLogger::log('post.bulk_published', 'post', 0, count($posts) . ' posts published');
Use subjectId = 0 for operations that do not have a single subject entity.
In Spark commands
// In a custom BaseCommand subclass
ActivityLogger::log('cron.backup', 'system', 0, 'Scheduled backup completed');
CLI calls detect the absence of a session and record user_id = 0, username = 'system', ip_address = 'cli'.