PHP code example of ss-ipg / laravel-auditable

1. Go to this page and download the library: Download ss-ipg/laravel-auditable library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ss-ipg / laravel-auditable example snippets


'channels' => [
    // ...

    'audit' => [
        'driver' => 'daily',
        'path' => storage_path('logs/audit.log'),
        'level' => 'info',
        'days' => 14,
    ],
],

use SSIPG\Auditable\Attributes\Auditable;

#[Auditable]
class User extends Model
{
    // ...
}

// config/auditable.php

return [
    // Enable/disable audit logging at runtime
    'enabled' => env('AUDITABLE_ENABLED', false),

    // Environments where logging is permitted
    // Use ['*'] to allow all environments
    'environments' => ['local', 'production', 'staging'],

    // Log channel name (must exist in config/logging.php)
    'channel' => 'audit',

    // Context providers for adding custom metadata
    'context_providers' => [
        // App\Audit\CustomContextProvider::class,
    ],

    // Formatter class for serializing log entries
    'formatter' => SSIPG\Auditable\Formatters\JsonFormatter::class,
];

use SSIPG\Auditable\Attributes\Auditable;
use SSIPG\Auditable\Enums\AuditAction;

// Audit everything (default)
#[Auditable]
class User extends Model {}

// Only audit specific columns
#[Auditable(columns: ['email', 'status'])]
class User extends Model {}

// Audit all except certain columns
#[Auditable(exclude: ['cached_data', 'last_seen_at'])]
class User extends Model {}

// Redact sensitive values
#[Auditable(redact: ['password', 'api_key'])]
class User extends Model {}

// Only audit deletions (compliance mode)
#[Auditable(events: [AuditAction::Deleted, AuditAction::SoftDeleted])]
class HighVolumeModel extends Model {}

// Don't track original values on updates (smaller logs)
#[Auditable(withOriginal: false)]
class User extends Model {}

// Combined options
#[Auditable(
    columns: ['email', 'password', 'role'],
    redact: ['password'],
    events: [AuditAction::Updated, AuditAction::Deleted],
    withOriginal: false,
)]
class User extends Model {}

// In your model
protected $casts = ['is_active' => 'boolean'];

// These are considered equivalent (no update logged):
$model->is_active = true;
$model->is_active = 1;    // Cast to true
$model->is_active = '1';  // Cast to true

namespace App\Audit;

use Illuminate\Database\Eloquent\Model;
use SSIPG\Auditable\Contracts\AuditContextProvider;
use SSIPG\Auditable\Enums\AuditAction;

class CustomContextProvider implements AuditContextProvider
{
    public function getContext(Model $model, AuditAction $action): array
    {
        return [
            'custom_id' => $model->custom_id,
        ];
    }
}

'context_providers' => [
    App\Audit\CustomContextProvider::class,
],

namespace App\Audit;

use SSIPG\Auditable\Contracts\AuditFormatter;

class CustomFormatter implements AuditFormatter
{
    public function format(array $payload): string
    {
        // Return your formatted string
        return json_encode($payload, JSON_PRETTY_PRINT);
    }
}

'formatter' => App\Audit\CustomFormatter::class,

use Illuminate\Database\Eloquent\Relations\Pivot;
use SSIPG\Auditable\Attributes\Auditable;

#[Auditable]
class ProjectUserPivot extends Pivot
{
    protected $table = 'project_user';
}

// app/Models/Project.php
public function users(): BelongsToMany
{
    return $this->belongsToMany(User::class)->using(ProjectUserPivot::class);
}

// app/Models/User.php
public function projects(): BelongsToMany
{
    return $this->belongsToMany(Project::class)->using(ProjectUserPivot::class);
}

use SSIPG\Auditable\Facades\Audit;
use SSIPG\Auditable\Enums\AuditAction;

public function test_user_creation_is_audited(): void
{
    Audit::fake();

    User::create(['name' => 'John', 'email' => '[email protected]']);

    Audit::assertLogged(AuditAction::Created);
}

// Assert an action was logged
Audit::assertLogged(AuditAction::Created);
Audit::assertLogged(AuditAction::Updated);
Audit::assertLogged(AuditAction::Deleted);
Audit::assertLogged(AuditAction::SoftDeleted);
Audit::assertLogged(AuditAction::Restored);

// Assert with callback for detailed matching
Audit::assertLogged(
    action: AuditAction::Created,
    callback: fn (array $entry) => $entry['model'] === User::class
        && $entry['changes']['email'] === '[email protected]'
);

// Assert an action was NOT logged
Audit::assertNotLogged(AuditAction::Updated);

// Assert nothing was logged
Audit::assertNothingLogged();

// Assert exact count of entries
Audit::assertLoggedCount(2);

// Get all logged entries for inspection
$entries = Audit::logged();
$createdEntries = Audit::logged(AuditAction::Created);

[
    'action'   => AuditAction::Created,  // The action enum
    'model'    => 'App\\Models\\User',   // Model class name
    'model_id' => 123,                   // Model primary key
    'changes'  => [                      // Changed attributes
        'name' => 'John',
        'email' => '[email protected]',
    ],
]
bash
php artisan vendor:publish --tag=auditable-config