PHPackages                             zhortein/auditable-bundle - 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. [Database &amp; ORM](/categories/database)
4. /
5. zhortein/auditable-bundle

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

zhortein/auditable-bundle
=========================

Attribute-based audit trail &amp; history logging for Doctrine entities in Symfony, with optional Messenger async persistence.

1.0.0(6mo ago)136[3 PRs](https://github.com/Zhortein/auditable-bundle/pulls)MITPHPPHP &gt;=8.3CI passing

Since Dec 24Pushed 6mo agoCompare

[ Source](https://github.com/Zhortein/auditable-bundle)[ Packagist](https://packagist.org/packages/zhortein/auditable-bundle)[ RSS](/packages/zhortein-auditable-bundle/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (14)Versions (6)Used By (0)

Zhortein Auditable Bundle
=========================

[](#zhortein-auditable-bundle)

A lightweight Symfony bundle to automatically **audit and historize Doctrine ORM entity changes** (create/update/delete) with optional **async persistence** via Symfony Messenger.

> Designed for Symfony 7.4+ / 8.x, PHP 8.3+.

Features
--------

[](#features)

- ✅ Opt-in auditing with PHP Attributes:
    - `#[Audited]` on a Doctrine entity class to enable auditing
    - `#[AuditLabel('…')]` on an entity class to override the displayed label
    - `#[AuditIgnore]` on an entity property to exclude it from audits (PII/secrets/noise)
- ✅ Captures create / update / delete actions
- ✅ Stores audit records in a `History` entity (Doctrine ORM)
- ✅ Supports async writing using Symfony Messenger (recommended)
- ✅ Extensible: actor resolver, label strategy, change detector, writer…

Requirements
------------

[](#requirements)

- PHP 8.3+
- Symfony 7.4+ (Symfony 8.x supported)
- Doctrine ORM + DoctrineBundle
- Symfony Messenger (optional but recommended for async)

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

[](#installation)

```
composer require zhortein/auditable-bundle
```

If you **don’t** use Symfony Flex recipes, enable the bundle:

```
// config/bundles.php
return [
    // ...
    Zhortein\AuditableBundle\ZhorteinAuditableBundle::class => ['all' => true],
];
```

### Doctrine mapping &amp; migrations

[](#doctrine-mapping--migrations)

The bundle ships a Doctrine entity (`AuditEntry`). Its mapping is registered automatically by a compiler pass, so you **don't need** to declare a `doctrine.orm.mappings` entry manually.

**Generate and run migrations** after installation:

```
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
```

This creates the `audit_entry` table with the necessary schema for storing audit trail entries.

Quick start
-----------

[](#quick-start)

### 1) Mark entities as audited

[](#1-mark-entities-as-audited)

```
use Zhortein\AuditableBundle\Attribute\Audited;
use Zhortein\AuditableBundle\Attribute\AuditLabel;
use Zhortein\AuditableBundle\Attribute\AuditIgnore;

#[Audited]
#[AuditLabel('Customer')]
class Customer
{
    private string $email;

    #[AuditIgnore]
    private string $passwordHash;
}
```

### 2) (Recommended) Configure async message handling

[](#2-recommended-configure-async-message-handling)

By default, the bundle is configured for **async persistence** via Symfony Messenger.

#### Step A: Define the Messenger transport

[](#step-a-define-the-messenger-transport)

If your project doesn't already have a Messenger `async` transport, add one:

```
# config/packages/messenger.yaml
framework:
  messenger:
    transports:
      async: '%env(MESSENGER_TRANSPORT_DSN)%'
    routing:
      'Zhortein\AuditableBundle\Message\PersistAuditEntryMessage': async
```

See `config/packages/messenger.yaml.example` in the bundle for a complete configuration example.

#### Step B: Configure the bundle

[](#step-b-configure-the-bundle)

Create or update the bundle configuration:

```
# config/packages/zhortein_auditable.yaml
zhortein_auditable:
  enabled: true
  async:
    enabled: true
    transport: 'async'
```

See `config/packages/zhortein_auditable.yaml.example` in the bundle for all available options.

#### Synchronous mode (optional)

[](#synchronous-mode-optional)

If you prefer **synchronous persistence** (audit records written immediately without Messenger):

```
zhortein_auditable:
  enabled: true
  async:
    enabled: false
```

> **Note**: Async mode is recommended for production to avoid blocking request handling with database writes.

Configuration reference
-----------------------

[](#configuration-reference)

The bundle's configuration options are documented with comments in `config/packages/zhortein_auditable.yaml.example`.

**Key settings:**

- **`enabled`**: Master switch to enable/disable auditing globally (default: `true`)
- **`async.enabled`**: Use Messenger for async persistence (default: `true`)
- **`async.transport`**: Messenger transport name for audit messages (default: `'async'`)
- **`listener.track_insert/update/delete`**: Control which operations are tracked (all default to `true`)
- **`fields.max_string_length`**: Maximum length for serialized field values (default: `180`)
- **`fields.global_ignored`**: List of properties to always exclude from all entities (default: `[]`)

**Actor resolution:**

By default, the bundle uses Symfony Security to resolve the current user via `SecurityActorResolver`. No additional configuration is needed.

The resolver automatically handles:

- Regular authenticated users → stores user ID or user identifier
- Null users (not authenticated) → stores `null`
- Impersonation → stores both original user and impersonator IDs

What gets stored
----------------

[](#what-gets-stored)

Each `AuditEntry` record in the audit trail contains:

- **Entity metadata**: Fully qualified class name and entity ID
- **Action**: One of `create`, `update`, `delete`, or `log`
- **Level**: Severity level (`debug`, `info`, `warning`, `error`, `critical`)
- **Title &amp; Description**: Human-readable summary of the change
- **Context**: Optional context tag for grouping related entities
- **Actor**: User ID or identifier of who made the change (null if unauthenticated)
- **Impersonator**: Original user ID if the change was made during impersonation
- **Timestamp**: When the change occurred (as `DateTimeImmutable`)
- **Data**: JSON-encoded field changes (old value → new value), excluding `#[AuditIgnore]` properties

**Example audit entry for an update:**

```
Title: "Update [Customer] - 2 field(s) changed"
Description:
  - "Email: john@example.com → john.doe@example.com"
  - "Phone: +1234567890 → +1987654321"
Data: { "email": { "old": "john@example.com", "new": "john.doe@example.com" }, ... }

```

Security / PII
--------------

[](#security--pii)

This bundle is meant to help you build **auditable applications**—but you are responsible for what you store.

- Use `#[AuditIgnore]` for secrets (password hashes, tokens) and sensitive data that should not be persisted in audit logs.
- Consider encrypting audit payloads or restricting access to the History table depending on your domain constraints.

License
-------

[](#license)

MIT (see [LICENSE](LICENSE)\]).

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance67

Regular maintenance activity

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

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

192d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/82563246?v=4)[David Renard](/maintainers/Zhortein)[@Zhortein](https://github.com/Zhortein)

---

Top Contributors

[![Zhortein](https://avatars.githubusercontent.com/u/82563246?v=4)](https://github.com/Zhortein "Zhortein (7 commits)")

---

Tags

logsymfonydoctrineAudithistorySymfony BundleMessengerAuditable

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/zhortein-auditable-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/zhortein-auditable-bundle/health.svg)](https://phpackages.com/packages/zhortein-auditable-bundle)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M388](/packages/easycorp-easyadmin-bundle)[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1189.8k](/packages/rcsofttech-audit-trail-bundle)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1616.4k14](/packages/2lenet-crudit-bundle)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M738](/packages/sylius-sylius)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k61](/packages/open-dxp-opendxp)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M203](/packages/sulu-sulu)

PHPackages © 2026

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