PHPackages                             ez-php/audit - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. ez-php/audit

ActiveLibrary

ez-php/audit
============

Audit log module for ez-php — event-driven recording of entity lifecycle changes (CREATE, UPDATE, DELETE) into an audit\_logs table with a fluent query API.

1.2.0(1mo ago)00MITPHPPHP ^8.5CI passing

Since Mar 28Pushed 1mo agoCompare

[ Source](https://github.com/ez-php/audit)[ Packagist](https://packagist.org/packages/ez-php/audit)[ RSS](/packages/ez-php-audit/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (8)Versions (2)Used By (0)

ez-php/audit
============

[](#ez-phpaudit)

Event-driven audit log module for ez-php. Records entity lifecycle changes (CREATE, UPDATE, DELETE) to a database table and exposes a fluent query API.

Installation
------------

[](#installation)

```
composer require ez-php/audit
```

Register the service provider:

```
// provider/modules.php
return [
    \EzPhp\Audit\AuditServiceProvider::class,
];
```

`AuditServiceProvider` requires `DatabaseInterface` and `ez-php/events` (`EventServiceProvider`) to be registered before it.

Database Schema
---------------

[](#database-schema)

The module auto-creates the `audit_logs` table on first write (`ensureTable()`). For production use, prefer running a migration:

```
CREATE TABLE audit_logs (
    id          INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    entity_type VARCHAR(255) NOT NULL,
    entity_id   VARCHAR(255) NOT NULL,
    action      VARCHAR(10)  NOT NULL,  -- 'create', 'update', 'delete'
    old_values  JSON         DEFAULT NULL,
    new_values  JSON         DEFAULT NULL,
    user_id     VARCHAR(255) DEFAULT NULL,
    created_at  DATETIME     NOT NULL,
    INDEX       idx_audit_entity  (entity_type, entity_id),
    INDEX       idx_audit_created (created_at)
);
```

Usage
-----

[](#usage)

### Dispatching audit events from repositories

[](#dispatching-audit-events-from-repositories)

Audit records are created by dispatching events from repository methods:

```
use EzPhp\Audit\Event\EntityCreatedEvent;
use EzPhp\Audit\Event\EntityUpdatedEvent;
use EzPhp\Audit\Event\EntityDeletedEvent;
use EzPhp\Events\Event;

// On create:
Event::dispatch(new EntityCreatedEvent(
    entityType: User::class,
    entityId:   $user->id(),
    newValues:  $user->toArray(),
    userId:     $currentUserId,   // optional
));

// On update:
Event::dispatch(new EntityUpdatedEvent(
    entityType: User::class,
    entityId:   $user->id(),
    oldValues:  $previousValues,
    newValues:  $user->toArray(),
    userId:     $currentUserId,
));

// On delete:
Event::dispatch(new EntityDeletedEvent(
    entityType: User::class,
    entityId:   $user->id(),
    oldValues:  $user->toArray(),
    userId:     $currentUserId,
));
```

`AuditServiceProvider` registers `AuditListener` automatically — no manual listener registration needed.

### Querying the audit trail

[](#querying-the-audit-trail)

```
use EzPhp\Audit\AuditAction;
use EzPhp\Audit\AuditQuery;

// All audit records for a specific entity:
$records = AuditQuery::for(User::class, $userId)->get();

// Only UPDATE records:
$records = AuditQuery::for(User::class, $userId)
    ->action(AuditAction::UPDATE)
    ->get();

// Records from the last 30 days:
$records = AuditQuery::for(User::class, $userId)
    ->since(new DateTimeImmutable('-30 days'))
    ->get();

// Records up to a date by a specific user:
$records = AuditQuery::for(User::class, $userId)
    ->until(new DateTimeImmutable('2024-12-31'))
    ->byUser($adminId)
    ->get();

// Latest record only:
$latest = AuditQuery::for(User::class, $userId)->first();

// Count:
$count = AuditQuery::for(User::class, $userId)->count();
```

All filter methods return a clone — chaining does not modify the original query.

### Programmatic logging (without events)

[](#programmatic-logging-without-events)

```
use EzPhp\Audit\AuditLogger;
use EzPhp\Audit\AuditRecord;
use EzPhp\Audit\AuditAction;

$logger = new AuditLogger($pdo);
$logger->log(new AuditRecord(
    entityType: 'App\\Order',
    entityId:   '123',
    action:     AuditAction::UPDATE,
    oldValues:  ['status' => 'pending'],
    newValues:  ['status' => 'shipped'],
    userId:     'admin',
    createdAt:  new DateTimeImmutable(),
));
```

Design
------

[](#design)

**Integration via events, not ORM core.** Repositories dispatch `EntityCreatedEvent`, `EntityUpdatedEvent`, and `EntityDeletedEvent`. `AuditListener` (registered by the service provider) converts them to `AuditRecord` and writes to the database. No ORM kernel changes required.

**`AuditQuery` is immutable.** All filter methods (`action()`, `since()`, `until()`, `byUser()`, `limit()`) return a clone. Re-use the same base query safely.

**`ensureTable()` for zero-config development.** `AuditLogger` auto-creates `audit_logs` on first write, adapting DDL to the PDO driver (SQLite for tests, MySQL for production). Production deployments should prefer a migration.

**No hard ORM dependency.** Depends only on `ez-php/contracts` and `ez-php/events`. Works with any persistence mechanism that dispatches the provided event types.

API Reference
-------------

[](#api-reference)

### `AuditAction` (enum)

[](#auditaction-enum)

CaseValue`AuditAction::CREATE``'create'``AuditAction::UPDATE``'update'``AuditAction::DELETE``'delete'`### `AuditRecord` (value object)

[](#auditrecord-value-object)

PropertyTypeDescription`entityType``string`Class name or identifier`entityId``string`Primary key (cast to string)`action``AuditAction`What happened`oldValues``array`Before-state (empty for creates)`newValues``array`After-state (empty for deletes)`userId``string|null`Who triggered the change`createdAt``DateTimeImmutable`When it happenedStatic factories: `AuditRecord::fromCreated()`, `::fromUpdated()`, `::fromDeleted()`.

### `AuditQuery` (fluent query builder)

[](#auditquery-fluent-query-builder)

MethodDescription`AuditQuery::for(class, id)`Scope to entity; returns new query`->action(AuditAction)`Filter by action type`->since(DateTimeImmutable)`Filter by minimum created\_at`->until(DateTimeImmutable)`Filter by maximum created\_at`->byUser(int|string)`Filter by user\_id`->limit(int)`Limit result count`->get()`Execute; return `list``->first()`Return latest record or null`->count()`Return total count### Events

[](#events)

ClassWhen to dispatch`EntityCreatedEvent`Entity created`EntityUpdatedEvent`Entity updated`EntityDeletedEvent`Entity deleted

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance91

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a15a63c46d239d42b8ed4c2fe9adbc5fe99eb62f6e5bb90f08021e0c068e8b37?d=identicon)[AU9500](/maintainers/AU9500)

---

Top Contributors

[![AU9500](https://avatars.githubusercontent.com/u/122030400?v=4)](https://github.com/AU9500 "AU9500 (9 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ez-php-audit/health.svg)

```
[![Health](https://phpackages.com/badges/ez-php-audit/health.svg)](https://phpackages.com/packages/ez-php-audit)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
