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
ParameterDescription
$actionDot-notation action string (e.g. post.created, theme.activated)
$subjectTypeThe type of entity acted on (e.g. post, theme, plugin, user)
$subjectIdPrimary key of the entity
$descriptionHuman-readable description for the admin activity feed

What Is Recorded

Each call inserts one row into activity_logs:

ColumnValue
user_idCurrent authenticated user ID (or 0 for CLI/system)
usernameCurrent authenticated username (or 'system')
actionThe $action string
subject_typeThe $subjectType string
subject_idThe $subjectId integer
descriptionThe $description string
ip_address$_SERVER['REMOTE_ADDR'] (or CLI marker)
created_atNOW()

Common Action Strings

Pubvana core uses these action strings consistently. Extension code should follow the same convention:

ActionTriggered by
post.createdNew post saved
post.updatedPost edited
post.deletedPost trashed
post.publishedPost status changed to published
page.created / page.updatedPage CRUD
theme.activatedTheme switched
theme.deactivatedTheme disabled
plugin.activatedPlugin activated
plugin.deactivatedPlugin deactivated
widget.placedWidget instance added to area
settings.updatedAdmin settings saved
media.uploadedFile uploaded
user.created / user.updatedUser management
marketplace.installedExtension 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'.