AthenaeumAthenaeum
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
  • Version 10.x

    • Release Notes
    • Upgrade Guide
    • New to this...
    • Contribution Guide
    • Security Policy
    • Code of Conduct
    • Origin
  • ACL

    • Introduction
    • How to install
    • Setup
    • Permissions
    • Roles
    • Users
    • Cached Permissions
  • Antivirus

    • Introduction
    • How to install
    • Setup
    • How to use
    • Scanners

      • Introduction
      • ClamAV
      • Null
      • Custom
    • Events
    • PSR
  • Audit

    • Audit
    • How to install
    • Setup
    • Recording
    • Events
    • Formatting
  • Auth

    • Introduction
    • How to install
    • Fortify

      • Prerequisites
      • Exceptions

        • Failed Login Attempt
        • Password Reset Link Failure
      • Responses

        • Failed Password Reset Link
  • Circuits

    • Circuits
    • How to install
    • Setup
    • Usage
    • Events
  • Collections

    • Collections
    • How to install
    • Summation

      • Summation Collection
      • Items Processor
  • Config

    • Configuration Loader
    • How to install
    • Setup
    • Load Configuration Files
    • Custom File Parsers
  • Console

    • Command and Schedule Registration
    • How to install
    • Setup
    • Commands
    • Schedules
  • Container

    • IoC Service Container
    • How to install
    • Container
    • List Resolver
  • Core

    • Athenaeum Core Application
    • How to install
    • Setup
    • Usage

      • Configuration
      • Service Providers
      • Service Container
      • Events
      • Caching
      • Logging
      • Console
      • Task Scheduling
      • Exception Handling
      • Extending Core Application
      • Testing
  • Database

    • Introduction
    • How to install
    • Models

      • Instantiatable
      • Sluggable
    • Query

      • Criteria (Query Filter)
  • Dto

    • Data Transfer Object (DTO)
    • How to install
    • How to use
  • ETags

    • Introduction
    • How to install
    • Setup
    • ETags usage

      • How to use
      • Generators

        • Default Generator
        • Custom Generator
      • Eloquent Models
    • Http Request Preconditions

      • Introduction
      • Resource Context
      • Preconditions
      • Actions
      • RFC 9110

        • If-Match
        • If-Unmodified-Since
        • If-None-Match
        • If-Modified-Since
        • If-Range
      • Extensions

        • Introduction
        • Range
      • Range Validator
      • Download Stream
    • Macros
  • Events

    • Register Listeners and Subscribers
    • How to install
    • Setup
    • Listeners
    • Subscribers
  • Filters

    • Search Filter Utilities
    • Prerequisites
    • How to install
    • Setup
    • Processor
    • Filters Builder
    • Predefined Resources

      • Search Processor
      • Sorting Processor
      • Constraints Processor
      • Matching Processor
    • Tip: Create a base builder
  • Flysystem

    • Introduction
    • Database Adapter

      • Introduction
      • How to install
      • Setup
      • Data Deduplication
      • MIME-Type Detection
  • Http

    • Api

      • Http API
      • How to install
      • Setup
      • Resources

        • Introduction
        • Timestamps
        • Self-Link
        • Relations
        • Caching
        • Registrar
      • Requests

        • Introduction
        • List Resources
        • List Deleted
        • Show Resource
        • Create Resource
        • Update Resource
        • Delete Resource
        • List Related
        • Process Multiple Resources
        • Helpers
      • Middleware

        • Introduction
        • Request Must Be Json
        • Capture Fields To Select
        • Remove Response Payload
    • Clients

      • Http Clients
      • How to install
      • Setup
      • Basic Usage
      • Available Methods

        • Fluent Api
        • Protocol Version
        • Base Uri
        • Http Method and Uri
        • Headers
        • Accept & Content-Type
        • Authentication
        • Http Query
        • Payload Format
        • Payload
        • Attachments
        • Cookies
        • Response Expectations
        • Middleware
        • Conditions
        • Criteria
        • Redirects
        • Timeout
        • Debugging
        • Logging
        • Driver Options
        • Driver
      • Http Query Builder

        • Introduction
        • Select
        • Where
        • Dates
        • Include
        • Pagination
        • Sorting
        • Raw Expressions
        • Custom Grammar
    • Cookies

      • Http Cookies
      • How to install
      • Usage
    • Messages

      • Http Messages
      • How to install
      • Serializers
  • Maintenance

    • Modes

      • Maintenance Modes
      • How to install
      • Setup
      • Basic Usage
      • Available Drivers
  • Mime Types

    • MIME-Types
    • How to install
    • Setup
    • Usage
    • Drivers

      • Available Drivers
      • File Info
  • Properties

    • Properties Overload
    • How to install
    • Usage
    • Naming Convention
    • Properties Visibility
  • Redmine

    • Redmine Api Client
    • How to install
    • Setup
    • General Usage

      • Supported Operations
      • Fetch list of resources
      • Find
      • Fetch
      • Create new record
      • Update existing record
      • Delete existing record
      • Relations
    • Available Resources

      • Predefined Resources
      • Attachments
      • Enumerations
      • Issue Relations
      • Users
      • User Groups
      • Roles
      • Project Memberships
      • Versions (Milestones)
      • Issue Categories
      • Trackers
  • Service

    • Service Registrar
    • How to install
    • How to use
  • Streams

    • Streams
    • How to install
    • Setup
    • How to use

      • Introduction
      • Open and Close
      • Raw Resource
      • Seeking
      • Reading
      • Writing
      • Size
      • Truncate
      • Sync
      • Flush
      • Hash
      • MIME-Type
      • Filename
      • Output
      • Locking
      • Transactions
      • Meta
      • Misc
  • Support

    • Introduction
    • How to install
    • Laravel Aware-of Helpers

      • How to use
      • Enforce Via Interface
      • Custom Default
      • Pros and Cons
      • Available Helpers
    • Env File
    • Aware-of Properties

      • Generator
    • Live Templates
  • Testing

    • Introduction
    • How to install
    • Test Cases
    • Testing Aware-of Helpers
  • Translation

    • Introduction
    • How to install
    • Exporters

      • Introduction
      • Setup
      • How to use
      • Drivers

        • Introduction
        • Array
        • Lang.js (Array)
        • Lang.js (JSON)
        • Cache
  • Utils

    • Introduction
    • How to install
    • Array
    • Duration
    • Json
    • Math
    • Memory
    • Method Helper
    • Invoker
    • Populatable
    • String
    • Version
  • Validation

    • Introduction
    • How to install
    • Setup
    • Rules

      • Alpha-Dash-Dot
      • Date Format
      • Semantic Version

Formatting

  • Audit Trail Formatter
    • Enable Formatter
  • Hide Attributes
    • Hidden attributes in Model
    • Timestamps
  • Format Attributes
  • Format Message
  • Omit Changes for specific Events
  • Onward

Audit Trail Formatter

To customise a model's audit trail entries, create a Formatter class and enable it for your model.

namespace Acme\Models\Users\Audit;

use Aedart\Audit\Formatters\BaseFormatter;

class UserAuditTrailFormatter extends BaseFormatter
{
    // ...remaining not shown here...
}

Enable Formatter

Specify your formatter's classpath in the auditTrailRecordFormatter() method, inside your model.

namespace Acme\Models;

use Acme\Models\Users\Audit\UserAuditTrailFormatter;
use Aedart\Contracts\Audit\Formatter;
use Aedart\Audit\Concerns\ChangeRecording;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use ChangeRecording;
    
    public function auditTrailRecordFormatter(): string|Formatter|null
    {
        return UserAuditTrailFormatter::class;
    }
}

Hide Attributes

Use the hide() method to prevent specific model attributes from being recorded in the audit trail.

use Illuminate\Database\Eloquent\Model;

class UserAuditTrailFormatter extends BaseFormatter
{
    public function __construct(Model $model)
    {
        parent::__construct($model);
        
        $this->hide([
            'last_login',
            'updated_at'
        ]);
    }
}

Default hidden

If you do not specify any hidden attributes in your formatter, then the following attributes are automatically marked as hidden:

  • Hidden Attribute (inside your Model)
  • Default Timestamps

Hidden attributes in Model

Regardless of what attributes you mark as hidden in your formatter, the model's hidden attributes are always excluded from audit trail entries.

class User extends Authenticatable
{
    use ChangeRecording;
    
    // These attributes are automaticall excluded in the audit trail!
    protected $hidden = [
        'password',
        'remember_token',
    ];
    
    //...remaining not shown
}

Timestamps

When you do mark certain attributes to be hidden from audit trail entries and also wish to hide your model's "regular" timestamps (created_at, updated_at and deleted_at), then you can obtain these using the timestampAttributes() method.

use Illuminate\Database\Eloquent\Model;

class UserAuditTrailFormatter extends BaseFormatter
{
    public function __construct(Model $model)
    {
        parent::__construct($model);
        
        $this->hide([
            $model->getKeyName(),
            'last_login',
            ...$this->timestampAttributes()
        ]);
    }
}

Format Attributes

To format your model's attributes, use the formatOriginal() and formatChanged() methods.
Both methods support the following arguments:

  • $data: The original or changed attributes, if available.
  • $type: The event type, e.g. created, updated, deleted, restored...etc.

For the sake of simplicity, the following example uses the same formatting for both the "original" and "changed" attributes.

class UserAuditTrailFormatter extends BaseFormatter
{
    // ...previous not shown...
    
    public function formatOriginal(array|null $data, string $type): array|null
    {
        return $this->applyFormatting($data, $type);
    }
    
    public function formatChanged(array|null $data, string $type): array|null
    {
        return $this->applyFormatting($data, $type);
    }
    
    /**
     * Your custom formatting method... 
     * 
     * @param array|null $data
     * @param string $type Ignored in this example...
     * 
     * @return array|null
     */
    public function applyFormatting(array|null $data, string $type): array|null
    {
        if (!isset($data)) {
            return null;
        }
        
        if (array_key_exists('job_id')) {
            $data['job'] = $this->getModel()->job->name;
            unset($data['job_id']);
        }
        
        return $data;
    }
}

Format Message

Depending on the circumstances, a change that results in a new audit trail entry might contain a custom message. The message can be modified via the formatMessage() method.

It accepts the following arguments:

  • $type: The event type, e.g. created, updated, deleted, restored...etc.
  • $message: Eventual message associated with the change.
use \Aedart\Contracts\Audit\Types;

class UserAuditTrailFormatter extends BaseFormatter
{
    // ...previous not shown...
    
    public function formatMessage(
        string $type,
        string|null $message = null
    ): string|null
    {
        // Use the provided message, if any... 
        if (isset($message)) {
            return $message;
        }
    
        // Provide a default message to be associated with the change...
        return match($type) {
            Types::CREATED => 'New user account was created',
            Types::UPDATED => 'User account was changed',
            Types::DELETED, Types::FORCE_DELETED => 'User account has been deleted',
            default => "{$type} event occurred, user account changed..."
        }
    }
}

Omit Changes for specific Events

In some situations, it might not be prudent to store any attributes (original or changed), in the audit trail entry. You can prevent all attributes from being stored in an entry, by using the omit() method. It accepts the following arguments:

  • $types: The event type(s), e.g. created, updated, deleted, restored...etc.
use Illuminate\Database\Eloquent\Model;

class UserAuditTrailFormatter extends BaseFormatter
{
    public function __construct(Model $model)
    {
        parent::__construct($model);
        
        $this->omit('my-custom-event');
    }
}

Default Behaviour

By default, changes are omitted for the following events:

  • deleted
  • force-deleted
  • restored

Onward

For additional possibilities to format and customise audit trail entries, please review the source code of \Aedart\Audit\Formatters\BaseFormatter.

Edit page
Last Updated: 15/02/2026, 09:39
Contributors: Alin Eugen Deac, alin, aedart
Prev
Events