Audit Changes Logs

This module logs all the actions by the users. Every time someone adds/updates/deletes an entry, it will log the action in database table audit_logs, which will be shown in a separate menu item (see above).

For that, we use Model Observer functionality of Laravel.

Video demo of a module:

How does the result look in QuickAdminPanel code?

We create a new database table with migration:

Schema::create('audit_logs', function (Blueprint $table) {
    $table->increments('id');
    $table->text('description');
    $table->unsignedInteger('subject_id')->nullable();
    $table->string('subject_type')->nullable();
    $table->unsignedInteger('user_id')->nullable();
    $table->text('properties')->nullable();
    $table->string('host', 45)->nullable();
    $table->timestamps();
});

Then we create a new model called app/AuditLog.php:

class AuditLog extends Model
{
    protected $fillable = [
        'description',
        'subject_id',
        'subject_type',
        'user_id',
        'properties',
        'host',
    ];

    protected $casts = [
        'properties' => 'collection',
    ];
}

Then we create one new Trait class, with this code. app/Traits/Auditable.php

namespace App\Traits;

use App\AuditLog;
use Illuminate\Database\Eloquent\Model;

trait Auditable
{
    public static function bootAuditable()
    {
        static::created(function (Model $model) {
            self::audit('created', $model);
        });

        static::updated(function (Model $model) {
            self::audit('updated', $model);
        });

        static::deleted(function (Model $model) {
            self::audit('deleted', $model);
        });
    }

    protected static function audit($description, $model)
    {
        AuditLog::create([
            'description'  => $description,
            'subject_id'   => $model->id ?? null,
            'subject_type' => get_class($model) ?? null,
            'user_id'      => auth()->id() ?? null,
            'properties'   => $model ?? null,
            'host'         => request()->ip() ?? null,
        ]);
    }
}

Then we attach this trait for CRUD model: app/Project.php:

use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Project extends Model
{
    use SoftDeletes, Auditable;

    // ...

Finally, we create a CRUD called Audit Logs to just view the table. resources/views/admin/auditLogs/index.blade.php

<table class=" table table-bordered table-striped datatable">
<thead>
<tr>
<th>
    {{ trans('global.auditLog.fields.id') }}
</th>
<th>
    {{ trans('global.auditLog.fields.description') }}
</th>
<th>
    {{ trans('global.auditLog.fields.subject_id') }}
</th>
<th>
    {{ trans('global.auditLog.fields.subject_type') }}
</th>
<th>
    {{ trans('global.auditLog.fields.user_id') }}
</th>
<th>
    {{ trans('global.auditLog.fields.host') }}
</th>
<th>
    {{ trans('global.auditLog.fields.created_at') }}
</th>
<th>
 
</th>
</tr>
</thead>
<tbody>
@foreach($auditLogs as $key => $auditLog)
<tr>
    <td>
        {{ $auditLog->id ?? '' }}
    </td>
    <td>
        {{ $auditLog->description ?? '' }}
    </td>
    <td>
        {{ $auditLog->subject_id ?? '' }}
    </td>
    <td>
        {{ $auditLog->subject_type ?? '' }}
    </td>
    <td>
        {{ $auditLog->user_id ?? '' }}
    </td>
    <td>
        {{ $auditLog->host ?? '' }}
    </td>
    <td>
        {{ $auditLog->created_at ?? '' }}
    </td>
    <td>
        @can('audit_log_show')
            <a class="btn btn-xs btn-primary" href="{{ route('admin.audit-logs.show', $auditLog->id) }}">
                {{ trans('global.view') }}
            </a>
        @endcan
        @can('audit_log_edit')
            <a class="btn btn-xs btn-info" href="{{ route('admin.audit-logs.edit', $auditLog->id) }}">
                {{ trans('global.edit') }}
            </a>
        @endcan
        @can('audit_log_delete')
            <form action="{{ route('admin.audit-logs.destroy', $auditLog->id) }}" method="POST" onsubmit="return confirm('{{ trans('global.areYouSure') }}');" style="display: inline-block;">
                <input type="hidden" name="_method" value="DELETE">
                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                <input type="submit" class="btn btn-xs btn-danger" value="{{ trans('global.delete') }}">
            </form>
        @endcan
    </td>

</tr>
@endforeach
</tbody>
</table>

You can easily customize the module after download by adding more fields or more logic in the files above.

How to install/use the module?

All you need to do is go to your panel's Modules menu item, find the module in the list and click Install.

Then for every CRUD you may specify to enable Audit Logs for that CRUD.

How to Customize the Module

More information

Last updated