PHP code example of gsebastiao / laravel-auditable
1. Go to this page and download the library: Download gsebastiao/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/ */
gsebastiao / laravel-auditable example snippets
namespace App\Models;
use Gsebastiao\Auditable\Concerns\Auditable;
use Illuminate\Database\Eloquent\Model;
class Produto extends Model
{
use Auditable;
protected $fillable = ['nome', 'preco', 'status_id'];
}
namespace App\Models;
use Gsebastiao\Auditable\Concerns\Auditable;
use Gsebastiao\Auditable\Support\AuditOptions;
use Gsebastiao\Auditable\Support\ResolveMap;
use Illuminate\Database\Eloquent\Model;
class Produto extends Model
{
use Auditable;
public function getAuditOptions(): AuditOptions
{
return AuditOptions::defaults()
->resolveMap([
'status_id' => ResolveMap::direct('Status', 'status', 'nome'),
]);
}
}
'status_id' => ResolveMap::direct('Status', 'status', 'nome'),
'categoria_id' => ResolveMap::direct('Categoria', 'categorias', 'titulo'),
// Parâmetros: (nome no log, tabela, coluna com o texto = 'nome', coluna procurada = 'id', filtros extra = [])
'tipo_id' => ResolveMap::direct('Tipo', 'tabelas_gerais', 'descricao', scope: ['grupo' => 'tipo_cliente']),
'estado_id' => ResolveMap::join([
// 1º item: a tabela onde está o valor gravado no campo
['table' => 'estados', 'key' => 'id'],
// itens seguintes: cada ligação (LEFT JOIN); no último, o que mostrar
['table' => 'paises',
'on' => ['paises.id', '=', 'estados.pais_id'],
'column' => 'nome',
'label' => 'País'],
]),
'preco_venda' => ResolveMap::alias('Preço de venda'),
public function getAuditOptions(): AuditOptions
{
return AuditOptions::defaults()
->events(['created', 'updated']) // não registrar exclusões
->except(['observacao_interna']) // nunca mostrar este campo
->resolveMap([
'status_id' => ResolveMap::direct('Status', 'status', 'nome'),
]);
}
$audit->user?->name; // null quando a ação foi do sistema
$pedido->operation()->get(); // a ÚLTIMA operação em que o pedido participou (todas as tabelas)
$pedido->operations()->get(); // TODAS as operações do pedido, com todas as linhas de cada uma
$pedido->audits()->get(); // só as linhas do próprio pedido
Pedido::operationFor(42)->get(); // o mesmo, sem carregar o pedido
Pedido::operationsFor(42)->get();
Audit::inBatch($batch)->get(); // tudo de um batch
Audit::transaction(function () use ($dados) {
$pedido = Pedido::create($dados);
EmitirNotaFiscal::dispatch($pedido->id); // uma job comum, sem código de auditoria
});
// Outro autor (ex.: num job da fila)
$pedido = Pedido::create($dados)->audit(createdBy: $this->userId);
// Outro nome de evento: em vez de "created", grava "importado"
$produto = Produto::create($linha)->audit(event: 'importado');
// Informação técnica extra
$produto->update($dados);
$produto->audit(debugInfo: ['origem' => 'api-parceiro']);
use Gsebastiao\Auditable\Audit;
use Gsebastiao\Auditable\Support\ResolveMap;
use Illuminate\Support\Facades\DB;
DB::table('pessoas')->where('id', $id)->update(['estado_id' => 7]);
Audit::for('pessoa', $id, 'updated')
->changes(['estado_id' => ['old' => 3, 'new' => 7]])
->resolveMap(['estado_id' => ResolveMap::direct('Estado', 'estados')])
->save();
use Gsebastiao\Auditable\Audit;
// De um registro
$produto->audits()->latest()->get();
Produto::auditsFor(42)->get(); // sem carregar o produto (já vem do mais novo para o mais antigo)
Produto::auditsFor(42)->action('updated')->get();
// Da aplicação inteira
Audit::byUser(auth()->id())->latest()->limit(20)->get();
Audit::action(['aprovado', 'reprovado'])->get();
Audit::failures()->whereDate('created_at', today())->get();
Audit::forRecord(Produto::class, 42)->get();
$audit->user; // o usuário (ou null)
$audit->subject; // o registro auditado (null se foi apagado) — só em auditorias de models
$audit->changes; // array com o que mudou
$audit->changeLines(); // o mesmo, em texto: ['Preco: 20 → 25', 'Status: Ativo → Bloqueado']
$audit->isFailure(); // foi uma falha?
public function show(Produto $produto)
{
$historico = $produto->audits()->with('user')->latest()->get();
return view('produtos.show', compact('produto', 'historico'));
}
use Illuminate\Support\Facades\Gate;
Gate::define('ver-auditoria', fn ($user) => $user->is_admin);
use Gsebastiao\Auditable\Audit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/auditoria', function (Request $request) {
$audits = Audit::filter($request->all())
->with('user')
->latest()
->orderByDesc('id')
->paginate(30)
->withQueryString();
return view('auditoria.index', ['audits' => $audits]);
})->middleware('auth')->can('ver-auditoria');
use App\Models\Produto;
use Gsebastiao\Auditable\Support\AuditColumnJoiner;
$query = Produto::query()->where('ativo', true);
AuditColumnJoiner::apply($query, Produto::class);
$produtos = $query->paginate(20);
AuditColumnJoiner::apply(
$query,
Produto::class,
actions: ['created', 'updated', 'aprovado'], // cada ação vira audit_<acao>_by e audit_<acao>_at
userColumn: 'email', // coluna da tabela de usuários a mostrar
dateFormat: 'DD/MM/YYYY', // ou null para a data crua
);
use App\Models\Produto;
use Gsebastiao\Auditable\Support\AuditWidget;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth')->group(function () {
// Para o GaAudit.full
Route::post('/auditoria/produtos/completo', function (Request $request) {
$id = $request->integer('id');
return AuditWidget::full(Produto::operationsFor($id), recordId: $id);
});
// Para o GaAudit.simple
Route::post('/auditoria/produtos/resumo', function (Request $request) {
return AuditWidget::simple(Produto::auditsFor($request->integer('id')));
});
});
$audit->restore(withId: false); // recria com um id novo
// Campos de neverSnapshot() (como password) não foram guardados.
// Se a coluna for obrigatória, informe um valor:
$audit->restore(attributes: ['password' => Hash::make(Str::random(16))]);
$audit->isRestorable(); // esta auditoria pode ser restaurada?
> try {
> Audit::transaction(function () use ($fatura) {
> // ...
> });
> } catch (\Throwable $e) {
> $fatura->auditFailure('cobranca', $e); // fora da transação: fica gravada
>
> throw $e;
> }
>
Schema::table('audit_table', function (Blueprint $table) {
$table->unsignedBigInteger('tenant_id')->nullable()->index();
});
use Gsebastiao\Auditable\Audit;
public function boot(): void
{
Audit::resolveTenantUsing(fn () => auth()->user()?->empresa_id);
}
use Gsebastiao\Auditable\Concerns\Auditable;
use Gsebastiao\Auditable\Concerns\BelongsToTenant;
class Produto extends Model
{
use Auditable, BelongsToTenant;
}
use Gsebastiao\Auditable\Audit;
// Só um trecho de código (seeders, importações, correções em massa)
Audit::withoutAuditing(function () {
Produto::factory()->count(500)->create();
});
namespace App\Models;
use Gsebastiao\Auditable\Models\Audit as BaseAudit;
class Auditoria extends BaseAudit
{
// opcional: outra tabela (senão usa config('auditable.table'))
// protected $table = 'historico';
}